mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 22:03:42 -07:00
Merge branch 'master' into master
Signed-off-by: Gary Bell <github@whiteneon.com>
This commit is contained in:
commit
783daad6ae
37 changed files with 613 additions and 257 deletions
|
@ -5,6 +5,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
- Fixed missing require of ansicolors in `lf_hid_bulkclone_v2.lua` script (@whiteneon)
|
- Fixed missing require of ansicolors in `lf_hid_bulkclone_v2.lua` script (@whiteneon)
|
||||||
- Added `lf_t55xx_reset.lua` - a script to aid in quickly resetting t55xx chips (@whiteneon)
|
- Added `lf_t55xx_reset.lua` - a script to aid in quickly resetting t55xx chips (@whiteneon)
|
||||||
|
- Added more fingerprinting in `hf mf info` (@doegox)
|
||||||
|
- Added --issue and (--emu)lator support to `hf iclass encode` command (@micsen)
|
||||||
|
- Added custom CTF Wiegand format from Defcon32 with comments (@micsen)
|
||||||
|
- Added native output grabbing for Python and Lua: less hacky than `output_grabber.py`, should work on ProxSpace as well (@doegox)
|
||||||
- Changed `hf mf chk/fchk`: added option `--no-default` to skip loading the usual ~61 hardcoded keys (@doegox)
|
- Changed `hf mf chk/fchk`: added option `--no-default` to skip loading the usual ~61 hardcoded keys (@doegox)
|
||||||
- Fixed `hf mf wipe` to detect properly write errors (@doegox)
|
- Fixed `hf mf wipe` to detect properly write errors (@doegox)
|
||||||
- Fixed `hf mf fchk` which was leaving the RF field on when interrupted by keyboard (@doegox)
|
- Fixed `hf mf fchk` which was leaving the RF field on when interrupted by keyboard (@doegox)
|
||||||
|
|
|
@ -394,7 +394,7 @@ ifeq ($(PYTHON_FOUND),1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#######################################################################################################
|
#######################################################################################################
|
||||||
# macOS doesn't like this params
|
# clang doesn't like this params
|
||||||
#MYCFLAGS += --param max-completely-peeled-insns=1000 --param max-completely-peel-times=10000
|
#MYCFLAGS += --param max-completely-peeled-insns=1000 --param max-completely-peel-times=10000
|
||||||
MYCFLAGS += -O3
|
MYCFLAGS += -O3
|
||||||
|
|
||||||
|
|
|
@ -2529,3 +2529,5 @@ bd6af9754c18
|
||||||
60FCB3C42ABF
|
60FCB3C42ABF
|
||||||
# key for hotel in greece
|
# key for hotel in greece
|
||||||
722F24F0722F
|
722F24F0722F
|
||||||
|
# STS Hotel 2A
|
||||||
|
535453535453
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
../../pm3 -c "script run testembedded_grab.py" -i
|
|
|
@ -1,4 +1,13 @@
|
||||||
local pm3 = require("pm3")
|
local pm3 = require("pm3")
|
||||||
p=pm3.pm3()
|
p=pm3.pm3()
|
||||||
|
|
||||||
p:console("hw status")
|
p:console("hw status")
|
||||||
print(p.name)
|
p:console("hw version")
|
||||||
|
for line in p.grabbed_output:gmatch("[^\r\n]+") do
|
||||||
|
if line:find("Unique ID") or line:find("uC:") then
|
||||||
|
print(line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Device:", p.name)
|
||||||
|
p:console("Rem passthru remark! :coffee:", true)
|
||||||
|
|
|
@ -2,5 +2,13 @@
|
||||||
|
|
||||||
import pm3
|
import pm3
|
||||||
p=pm3.pm3()
|
p=pm3.pm3()
|
||||||
|
|
||||||
p.console("hw status")
|
p.console("hw status")
|
||||||
|
p.console("hw version")
|
||||||
|
for line in p.grabbed_output.split('\n'):
|
||||||
|
if "Unique ID" in line:
|
||||||
|
print(line)
|
||||||
|
if "uC:" in line:
|
||||||
|
print(line)
|
||||||
print("Device:", p.name)
|
print("Device:", p.name)
|
||||||
|
p.console("Rem passthru remark! :coffee:", True)
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import pm3
|
|
||||||
from output_grabber import OutputGrabber
|
|
||||||
|
|
||||||
out = OutputGrabber()
|
|
||||||
p=pm3.pm3()
|
|
||||||
print("Device:", p.name)
|
|
||||||
with out:
|
|
||||||
p.console("hw status")
|
|
||||||
for line in out.captured_output.split('\n'):
|
|
||||||
if "Unique ID" in line:
|
|
||||||
print(line)
|
|
|
@ -2,5 +2,14 @@
|
||||||
|
|
||||||
local pm3 = require("pm3")
|
local pm3 = require("pm3")
|
||||||
p=pm3.pm3("/dev/ttyACM0")
|
p=pm3.pm3("/dev/ttyACM0")
|
||||||
|
|
||||||
p:console("hw status")
|
p:console("hw status")
|
||||||
print(p.name)
|
p:console("hw version")
|
||||||
|
for line in p.grabbed_output:gmatch("[^\r\n]+") do
|
||||||
|
if line:find("Unique ID") or line:find("uC:") then
|
||||||
|
print(line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Device:", p.name)
|
||||||
|
p:console("Rem passthru remark! :coffee:", true)
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
PYTHONPATH=../../pyscripts ipython3 -i ./test_grab.py
|
|
|
@ -2,5 +2,13 @@
|
||||||
|
|
||||||
import pm3
|
import pm3
|
||||||
p=pm3.pm3("/dev/ttyACM0")
|
p=pm3.pm3("/dev/ttyACM0")
|
||||||
|
|
||||||
p.console("hw status")
|
p.console("hw status")
|
||||||
|
p.console("hw version")
|
||||||
|
for line in p.grabbed_output.split('\n'):
|
||||||
|
if "Unique ID" in line:
|
||||||
|
print(line)
|
||||||
|
if "uC:" in line:
|
||||||
|
print(line)
|
||||||
print("Device:", p.name)
|
print("Device:", p.name)
|
||||||
|
p.console("Rem passthru remark! :coffee:", True)
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import pm3
|
|
||||||
from output_grabber import OutputGrabber
|
|
||||||
|
|
||||||
out = OutputGrabber()
|
|
||||||
p=pm3.pm3("/dev/ttyACM0")
|
|
||||||
print("Device:", p.name)
|
|
||||||
with out:
|
|
||||||
p.console("hw status")
|
|
||||||
for line in out.captured_output.split('\n'):
|
|
||||||
if "Unique ID" in line:
|
|
||||||
print(line)
|
|
|
@ -16,10 +16,13 @@
|
||||||
#ifndef LIBPM3_H
|
#ifndef LIBPM3_H
|
||||||
#define LIBPM3_H
|
#define LIBPM3_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct pm3_device pm3;
|
typedef struct pm3_device pm3;
|
||||||
|
|
||||||
pm3 *pm3_open(const char *port);
|
pm3 *pm3_open(const char *port);
|
||||||
int pm3_console(pm3 *dev, const char *cmd);
|
int pm3_console(pm3 *dev, const char *cmd, bool passthru);
|
||||||
|
const char *pm3_grabbed_output_get(pm3 *dev);
|
||||||
const char *pm3_name_get(pm3 *dev);
|
const char *pm3_name_get(pm3 *dev);
|
||||||
void pm3_close(pm3 *dev);
|
void pm3_close(pm3 *dev);
|
||||||
pm3 *pm3_get_current_dev(void);
|
pm3 *pm3_get_current_dev(void);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
# * 16 random keys with keyA==keyB in each sector: ~30 min
|
# * 16 random keys with keyA==keyB in each sector: ~30 min
|
||||||
# * 24 random keys, some reused across sectors: <1 min
|
# * 24 random keys, some reused across sectors: <1 min
|
||||||
#
|
#
|
||||||
# Doegox, 2024
|
# Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -19,7 +19,6 @@ import time
|
||||||
import subprocess
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
import pm3
|
import pm3
|
||||||
from output_grabber import OutputGrabber
|
|
||||||
# optional color support
|
# optional color support
|
||||||
try:
|
try:
|
||||||
# pip install ansicolors
|
# pip install ansicolors
|
||||||
|
@ -33,16 +32,23 @@ BACKDOOR_RF08S = "A396EFA4E24F"
|
||||||
NUM_SECTORS = 16
|
NUM_SECTORS = 16
|
||||||
if os.path.basename(os.path.dirname(os.path.dirname(sys.argv[0]))) == 'client':
|
if os.path.basename(os.path.dirname(os.path.dirname(sys.argv[0]))) == 'client':
|
||||||
# dev setup
|
# dev setup
|
||||||
TOOLS_PATH = f"{os.path.dirname(sys.argv[0])}/../../tools/mfc/card_only"
|
TOOLS_PATH = os.path.normpath(os.path.join(f"{os.path.dirname(sys.argv[0])}",
|
||||||
|
"..", "..", "tools", "mfc", "card_only"))
|
||||||
else:
|
else:
|
||||||
# assuming installed
|
# assuming installed
|
||||||
TOOLS_PATH = f"{os.path.dirname(sys.argv[0])}/../tools"
|
TOOLS_PATH = os.path.normpath(os.path.join(f"{os.path.dirname(sys.argv[0])}",
|
||||||
|
"..", "tools"))
|
||||||
|
|
||||||
STATICNESTED_1NT = f"{TOOLS_PATH}/staticnested_1nt"
|
tools = {
|
||||||
STATICNESTED_2X1NT = f"{TOOLS_PATH}/staticnested_2x1nt_rf08s"
|
"staticnested_1nt": os.path.join(f"{TOOLS_PATH}", "staticnested_1nt"),
|
||||||
STATICNESTED_2X1NT1KEY = f"{TOOLS_PATH}/staticnested_2x1nt_rf08s_1key"
|
"staticnested_2x1nt": os.path.join(f"{TOOLS_PATH}", "staticnested_2x1nt_rf08s"),
|
||||||
for bin in [STATICNESTED_1NT, STATICNESTED_2X1NT, STATICNESTED_2X1NT1KEY]:
|
"staticnested_2x1nt1key": os.path.join(f"{TOOLS_PATH}", "staticnested_2x1nt_rf08s_1key"),
|
||||||
|
}
|
||||||
|
for tool, bin in tools.items():
|
||||||
if not os.path.isfile(bin):
|
if not os.path.isfile(bin):
|
||||||
|
if os.path.isfile(bin + ".exe"):
|
||||||
|
tools[tool] = bin + ".exe"
|
||||||
|
else:
|
||||||
print(f"Cannot find {bin}, abort!")
|
print(f"Cannot find {bin}, abort!")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
@ -54,27 +60,24 @@ parser.add_argument('-d', '--debug', action='store_true', help='Enable debug mod
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
out = OutputGrabber()
|
|
||||||
p = pm3.pm3()
|
p = pm3.pm3()
|
||||||
|
|
||||||
restore_color = False
|
restore_color = False
|
||||||
with out:
|
p.console("prefs get color")
|
||||||
p.console("prefs get color")
|
p.console("prefs set color --off")
|
||||||
p.console("prefs set color --off")
|
for line in p.grabbed_output.split('\n'):
|
||||||
for line in out.captured_output.split('\n'):
|
|
||||||
if "ansi" in line:
|
if "ansi" in line:
|
||||||
restore_color = True
|
restore_color = True
|
||||||
with out:
|
p.console("hf 14a read")
|
||||||
p.console("hf 14a read")
|
|
||||||
uid = None
|
uid = None
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "UID:" in line:
|
if "UID:" in line:
|
||||||
uid = int(line[10:].replace(' ', ''), 16)
|
uid = int(line[10:].replace(' ', ''), 16)
|
||||||
if uid is None:
|
if uid is None:
|
||||||
print("Card not found")
|
print("Card not found")
|
||||||
if restore_color:
|
if restore_color:
|
||||||
with out:
|
|
||||||
p.console("prefs set color --ansi")
|
p.console("prefs set color --ansi")
|
||||||
|
_ = p.grabbed_output
|
||||||
exit()
|
exit()
|
||||||
print("UID: " + color(f"{uid:08X}", fg="green"))
|
print("UID: " + color(f"{uid:08X}", fg="green"))
|
||||||
|
|
||||||
|
@ -87,9 +90,8 @@ def print_key(sec, key_type, key):
|
||||||
found_keys = [["", ""] for _ in range(NUM_SECTORS)]
|
found_keys = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
if not args.no_init_check:
|
if not args.no_init_check:
|
||||||
print("Checking default keys...")
|
print("Checking default keys...")
|
||||||
with out:
|
|
||||||
p.console("hf mf fchk")
|
p.console("hf mf fchk")
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "[+] 0" in line:
|
if "[+] 0" in line:
|
||||||
res = [x.strip() for x in line.split('|')]
|
res = [x.strip() for x in line.split('|')]
|
||||||
sec = int(res[0][4:])
|
sec = int(res[0][4:])
|
||||||
|
@ -104,8 +106,7 @@ nt = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
nt_enc = [["", ""] for _ in range(NUM_SECTORS)]
|
nt_enc = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
par_err = [["", ""] for _ in range(NUM_SECTORS)]
|
par_err = [["", ""] for _ in range(NUM_SECTORS)]
|
||||||
print("Getting nonces...")
|
print("Getting nonces...")
|
||||||
with out:
|
for sec in range(NUM_SECTORS):
|
||||||
for sec in range(NUM_SECTORS):
|
|
||||||
blk = sec * 4
|
blk = sec * 4
|
||||||
if found_keys[sec][0] == "" or found_keys[sec][1] == "":
|
if found_keys[sec][0] == "" or found_keys[sec][1] == "":
|
||||||
# Even if one key already found, we'll need both nt
|
# Even if one key already found, we'll need both nt
|
||||||
|
@ -115,7 +116,7 @@ with out:
|
||||||
cmd += f" --c2 {key_type}"
|
cmd += f" --c2 {key_type}"
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
print("Processing traces...")
|
print("Processing traces...")
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "nested cmd: 64" in line or "nested cmd: 65" in line:
|
if "nested cmd: 64" in line or "nested cmd: 65" in line:
|
||||||
sec = int(line[24:26], 16)//4
|
sec = int(line[24:26], 16)//4
|
||||||
key_type = int(line[21:23], 16) - 0x64
|
key_type = int(line[21:23], 16) - 0x64
|
||||||
|
@ -128,6 +129,17 @@ for line in out.captured_output.split('\n'):
|
||||||
nt_enc[sec][key_type] = data
|
nt_enc[sec][key_type] = data
|
||||||
data = line[128:136]
|
data = line[128:136]
|
||||||
par_err[sec][key_type] = data
|
par_err[sec][key_type] = data
|
||||||
|
for sec in range(NUM_SECTORS):
|
||||||
|
if found_keys[sec][0] == "" or found_keys[sec][1] == "":
|
||||||
|
for key_type in [0, 1]:
|
||||||
|
if (nt[sec][key_type] == "" or
|
||||||
|
nt_enc[sec][key_type] == "" or
|
||||||
|
par_err[sec][key_type] == ""):
|
||||||
|
print("Error, could not collect nonces, abort")
|
||||||
|
if restore_color:
|
||||||
|
p.console("prefs set color --ansi")
|
||||||
|
_ = p.grabbed_output
|
||||||
|
exit()
|
||||||
|
|
||||||
print("Running staticnested_1nt & 2x1nt when doable...")
|
print("Running staticnested_1nt & 2x1nt when doable...")
|
||||||
keys = [[set(), set()] for _ in range(NUM_SECTORS)]
|
keys = [[set(), set()] for _ in range(NUM_SECTORS)]
|
||||||
|
@ -140,12 +152,12 @@ for sec in range(NUM_SECTORS):
|
||||||
continue
|
continue
|
||||||
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]:
|
if found_keys[sec][0] == "" and found_keys[sec][1] == "" and nt[sec][0] != nt[sec][1]:
|
||||||
for key_type in [0, 1]:
|
for key_type in [0, 1]:
|
||||||
cmd = [STATICNESTED_1NT, f"{uid:08X}", f"{sec}",
|
cmd = [tools["staticnested_1nt"], f"{uid:08X}", f"{sec}",
|
||||||
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
subprocess.run(cmd, capture_output=True)
|
subprocess.run(cmd, capture_output=True)
|
||||||
cmd = [STATICNESTED_2X1NT,
|
cmd = [tools["staticnested_2x1nt"],
|
||||||
f"keys_{uid:08x}_{sec:02}_{nt[sec][0]}.dic", f"keys_{uid:08x}_{sec:02}_{nt[sec][1]}.dic"]
|
f"keys_{uid:08x}_{sec:02}_{nt[sec][0]}.dic", f"keys_{uid:08x}_{sec:02}_{nt[sec][1]}.dic"]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
|
@ -165,7 +177,7 @@ for sec in range(NUM_SECTORS):
|
||||||
key_type = 0
|
key_type = 0
|
||||||
else:
|
else:
|
||||||
key_type = 1
|
key_type = 1
|
||||||
cmd = [STATICNESTED_1NT, f"{uid:08X}", f"{sec}",
|
cmd = [tools["staticnested_1nt"], f"{uid:08X}", f"{sec}",
|
||||||
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
nt[sec][key_type], nt_enc[sec][key_type], par_err[sec][key_type]]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
|
@ -217,9 +229,8 @@ for sec in range(NUM_SECTORS):
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
with out:
|
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
|
@ -244,9 +255,8 @@ for sec in range(NUM_SECTORS):
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
with out:
|
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
|
@ -266,9 +276,8 @@ for sec in range(NUM_SECTORS):
|
||||||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
with out:
|
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
|
@ -293,7 +302,7 @@ for sec in range(NUM_SECTORS):
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_filtered.dic"
|
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}_filtered.dic"
|
||||||
else:
|
else:
|
||||||
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}.dic"
|
dic = f"keys_{uid:08x}_{sec:02}_{nt[sec][key_type_target]}.dic"
|
||||||
cmd = [STATICNESTED_2X1NT1KEY, nt[sec][key_type_source], found_keys[sec][key_type_source], dic]
|
cmd = [tools["staticnested_2x1nt1key"], nt[sec][key_type_source], found_keys[sec][key_type_source], dic]
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(' '.join(cmd))
|
print(' '.join(cmd))
|
||||||
result = subprocess.run(cmd, capture_output=True, text=True).stdout
|
result = subprocess.run(cmd, capture_output=True, text=True).stdout
|
||||||
|
@ -309,9 +318,8 @@ for sec in range(NUM_SECTORS):
|
||||||
cmd += f" -k {k}"
|
cmd += f" -k {k}"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
with out:
|
|
||||||
p.console(cmd)
|
p.console(cmd)
|
||||||
for line in out.captured_output.split('\n'):
|
for line in p.grabbed_output.split('\n'):
|
||||||
if "aborted via keyboard" in line:
|
if "aborted via keyboard" in line:
|
||||||
abort = True
|
abort = True
|
||||||
if "found:" in line:
|
if "found:" in line:
|
||||||
|
@ -323,8 +331,8 @@ for sec in range(NUM_SECTORS):
|
||||||
if abort:
|
if abort:
|
||||||
break
|
break
|
||||||
if restore_color:
|
if restore_color:
|
||||||
with out:
|
|
||||||
p.console("prefs set color --ansi")
|
p.console("prefs set color --ansi")
|
||||||
|
_ = p.grabbed_output
|
||||||
|
|
||||||
if abort:
|
if abort:
|
||||||
print("Brute-forcing phase aborted via keyboard!")
|
print("Brute-forcing phase aborted via keyboard!")
|
||||||
|
@ -374,10 +382,7 @@ else:
|
||||||
cmd = f"hf mf fchk -f keys_{uid:08x}.dic --no-default --dump"
|
cmd = f"hf mf fchk -f keys_{uid:08x}.dic --no-default --dump"
|
||||||
if args.debug:
|
if args.debug:
|
||||||
print(cmd)
|
print(cmd)
|
||||||
with out:
|
p.console(cmd, passthru = True)
|
||||||
p.console(cmd)
|
|
||||||
for line in out.captured_output.split('\n'):
|
|
||||||
print(line)
|
|
||||||
|
|
||||||
elapsed_time = time.time() - start_time
|
elapsed_time = time.time() - start_time
|
||||||
minutes = int(elapsed_time // 60)
|
minutes = int(elapsed_time // 60)
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
# From https://stackoverflow.com/a/29834357
|
|
||||||
class OutputGrabber(object):
|
|
||||||
"""
|
|
||||||
Class used to grab standard output or another stream.
|
|
||||||
"""
|
|
||||||
escape_char = "\b"
|
|
||||||
|
|
||||||
def __init__(self, stream=None, threaded=False):
|
|
||||||
self.origstream = stream
|
|
||||||
self.threaded = threaded
|
|
||||||
if self.origstream is None:
|
|
||||||
self.origstream = sys.stdout
|
|
||||||
self.origstreamfd = self.origstream.fileno()
|
|
||||||
self.captured_output = ""
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
self.start()
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, type, value, traceback):
|
|
||||||
self.stop()
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""
|
|
||||||
Start capturing the stream data.
|
|
||||||
"""
|
|
||||||
self.captured_output = ""
|
|
||||||
# Create a pipe so the stream can be captured:
|
|
||||||
self.pipe_out, self.pipe_in = os.pipe()
|
|
||||||
# Save a copy of the stream:
|
|
||||||
self.streamfd = os.dup(self.origstreamfd)
|
|
||||||
# Replace the original stream with our write pipe:
|
|
||||||
os.dup2(self.pipe_in, self.origstreamfd)
|
|
||||||
if self.threaded:
|
|
||||||
# Start thread that will read the stream:
|
|
||||||
self.workerThread = threading.Thread(target=self.readOutput)
|
|
||||||
self.workerThread.start()
|
|
||||||
# Make sure that the thread is running and os.read() has executed:
|
|
||||||
time.sleep(0.01)
|
|
||||||
|
|
||||||
def stop(self):
|
|
||||||
"""
|
|
||||||
Stop capturing the stream data and save the text in `captured_output`.
|
|
||||||
"""
|
|
||||||
# Print the escape character to make the readOutput method stop:
|
|
||||||
self.origstream.write(self.escape_char)
|
|
||||||
# Flush the stream to make sure all our data goes in before
|
|
||||||
# the escape character:
|
|
||||||
self.origstream.flush()
|
|
||||||
if self.threaded:
|
|
||||||
# wait until the thread finishes so we are sure that
|
|
||||||
# we have until the last character:
|
|
||||||
self.workerThread.join()
|
|
||||||
else:
|
|
||||||
self.readOutput()
|
|
||||||
# Close the pipe:
|
|
||||||
os.close(self.pipe_in)
|
|
||||||
os.close(self.pipe_out)
|
|
||||||
# Restore the original stream:
|
|
||||||
os.dup2(self.streamfd, self.origstreamfd)
|
|
||||||
# Close the duplicate stream:
|
|
||||||
os.close(self.streamfd)
|
|
||||||
|
|
||||||
def readOutput(self):
|
|
||||||
"""
|
|
||||||
Read the stream data (one byte at a time)
|
|
||||||
and save the text in `captured_output`.
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
char = os.read(self.pipe_out,1).decode(self.origstream.encoding, errors='replace')
|
|
||||||
if not char or self.escape_char in char:
|
|
||||||
break
|
|
||||||
self.captured_output += char
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
print("This is a library, don't use it as a script")
|
|
|
@ -1,13 +1,10 @@
|
||||||
# This file was automatically generated by SWIG (http://www.swig.org).
|
# This file was automatically generated by SWIG (https://www.swig.org).
|
||||||
# Version 4.0.2
|
# Version 4.2.1
|
||||||
#
|
#
|
||||||
# Do not make changes to this file unless you know what you are doing--modify
|
# Do not make changes to this file unless you know what you are doing - modify
|
||||||
# the SWIG interface file instead.
|
# the SWIG interface file instead.
|
||||||
|
|
||||||
from sys import version_info as _swig_python_version_info
|
from sys import version_info as _swig_python_version_info
|
||||||
if _swig_python_version_info < (2, 7, 0):
|
|
||||||
raise RuntimeError("Python 2.7 or later required")
|
|
||||||
|
|
||||||
# Import the low-level C/C++ module
|
# Import the low-level C/C++ module
|
||||||
if __package__ or "." in __name__:
|
if __package__ or "." in __name__:
|
||||||
from . import _pm3
|
from . import _pm3
|
||||||
|
@ -29,10 +26,10 @@ def _swig_repr(self):
|
||||||
|
|
||||||
def _swig_setattr_nondynamic_instance_variable(set):
|
def _swig_setattr_nondynamic_instance_variable(set):
|
||||||
def set_instance_attr(self, name, value):
|
def set_instance_attr(self, name, value):
|
||||||
if name == "thisown":
|
if name == "this":
|
||||||
self.this.own(value)
|
|
||||||
elif name == "this":
|
|
||||||
set(self, name, value)
|
set(self, name, value)
|
||||||
|
elif name == "thisown":
|
||||||
|
self.this.own(value)
|
||||||
elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
|
elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
|
||||||
set(self, name, value)
|
set(self, name, value)
|
||||||
else:
|
else:
|
||||||
|
@ -69,9 +66,10 @@ class pm3(object):
|
||||||
_pm3.pm3_swiginit(self, _pm3.new_pm3(*args))
|
_pm3.pm3_swiginit(self, _pm3.new_pm3(*args))
|
||||||
__swig_destroy__ = _pm3.delete_pm3
|
__swig_destroy__ = _pm3.delete_pm3
|
||||||
|
|
||||||
def console(self, cmd):
|
def console(self, cmd, passthru=False):
|
||||||
return _pm3.pm3_console(self, cmd)
|
return _pm3.pm3_console(self, cmd, passthru)
|
||||||
name = property(_pm3.pm3_name_get)
|
name = property(_pm3.pm3_name_get)
|
||||||
|
grabbed_output = property(_pm3.pm3_grabbed_output_get)
|
||||||
|
|
||||||
# Register pm3 in _pm3:
|
# Register pm3 in _pm3:
|
||||||
_pm3.pm3_swigregister(pm3)
|
_pm3.pm3_swigregister(pm3)
|
||||||
|
|
|
@ -4579,20 +4579,24 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
"Use either --bin or --wiegand/--fc/--cn",
|
"Use either --bin or --wiegand/--fc/--cn",
|
||||||
"hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337 (H10301)\n"
|
"hf iclass encode --bin 10001111100000001010100011 --ki 0 -> FC 31 CN 337 (H10301)\n"
|
||||||
"hf iclass encode -w H10301 --fc 31 --cn 337 --ki 0 -> FC 31 CN 337 (H10301)\n"
|
"hf iclass encode -w H10301 --fc 31 --cn 337 --ki 0 -> FC 31 CN 337 (H10301)\n"
|
||||||
"hf iclass encode --bin 10001111100000001010100011 --ki 0 --elite -> FC 31 CN 337 (H10301), writing w elite key"
|
"hf iclass encode --bin 10001111100000001010100011 --ki 0 --elite -> FC 31 CN 337 (H10301), writing w elite key\n"
|
||||||
|
"hf iclass encode -w H10301 --fc 31 --cn 337 --emu -> Writes the ecoded data to emulator memory\n"
|
||||||
|
"When using emulator you have to first load a credential into emulator memory"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
arg_str0(NULL, "bin", "<bin>", "Binary string i.e 0001001001"),
|
arg_str0(NULL, "bin", "<bin>", "Binary string i.e 0001001001"),
|
||||||
arg_int1(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
arg_int0(NULL, "ki", "<dec>", "Key index to select key from memory 'hf iclass managekeys'"),
|
||||||
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
arg_lit0(NULL, "credit", "key is assumed to be the credit key"),
|
||||||
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
arg_lit0(NULL, "elite", "elite computations applied to key"),
|
||||||
arg_lit0(NULL, "raw", "no computations applied to key"),
|
arg_lit0(NULL, "raw", "no computations applied to key"),
|
||||||
arg_str0(NULL, "enckey", "<hex>", "3DES transport key, 16 hex bytes"),
|
arg_str0(NULL, "enckey", "<hex>", "3DES transport key, 16 hex bytes"),
|
||||||
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
arg_u64_0(NULL, "fc", "<dec>", "facility code"),
|
||||||
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
arg_u64_0(NULL, "cn", "<dec>", "card number"),
|
||||||
|
arg_u64_0(NULL, "issue", "<dec>", "issue level"),
|
||||||
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
arg_str0("w", "wiegand", "<format>", "see " _YELLOW_("`wiegand list`") " for available formats"),
|
||||||
|
arg_lit0(NULL, "emu", "Write to emulation memory instead of card"),
|
||||||
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
arg_lit0(NULL, "shallow", "use shallow (ASK) reader modulation instead of OOK"),
|
||||||
arg_lit0("v", NULL, "verbose (print encoded blocks)"),
|
arg_lit0("v", NULL, "verbose (print encoded blocks)"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
|
@ -4605,9 +4609,18 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
CLIGetStrWithReturn(ctx, 1, bin, &bin_len);
|
CLIGetStrWithReturn(ctx, 1, bin, &bin_len);
|
||||||
|
|
||||||
int key_nr = arg_get_int_def(ctx, 2, -1);
|
int key_nr = arg_get_int_def(ctx, 2, -1);
|
||||||
bool auth = false;
|
bool use_emulator_memory = arg_get_lit(ctx, 11);
|
||||||
|
|
||||||
|
bool auth = false;
|
||||||
uint8_t key[8] = {0};
|
uint8_t key[8] = {0};
|
||||||
|
|
||||||
|
// If we use emulator memory skip key requirement
|
||||||
|
if (!use_emulator_memory) {
|
||||||
|
if (key_nr < 0) {
|
||||||
|
PrintAndLogEx(ERR, "Missing required arg for --ki or --emu");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (key_nr >= 0) {
|
if (key_nr >= 0) {
|
||||||
if (key_nr < ICLASS_KEYS_MAX) {
|
if (key_nr < ICLASS_KEYS_MAX) {
|
||||||
auth = true;
|
auth = true;
|
||||||
|
@ -4619,6 +4632,7 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool use_credit_key = arg_get_lit(ctx, 3);
|
bool use_credit_key = arg_get_lit(ctx, 3);
|
||||||
bool elite = arg_get_lit(ctx, 4);
|
bool elite = arg_get_lit(ctx, 4);
|
||||||
|
@ -4635,13 +4649,15 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
memset(&card, 0, sizeof(wiegand_card_t));
|
memset(&card, 0, sizeof(wiegand_card_t));
|
||||||
card.FacilityCode = arg_get_u32_def(ctx, 7, 0);
|
card.FacilityCode = arg_get_u32_def(ctx, 7, 0);
|
||||||
card.CardNumber = arg_get_u32_def(ctx, 8, 0);
|
card.CardNumber = arg_get_u32_def(ctx, 8, 0);
|
||||||
|
card.IssueLevel = arg_get_u32_def(ctx, 9, 0);
|
||||||
|
|
||||||
char format[16] = {0};
|
char format[16] = {0};
|
||||||
int format_len = 0;
|
int format_len = 0;
|
||||||
CLIParamStrToBuf(arg_get_str(ctx, 9), (uint8_t *)format, sizeof(format), &format_len);
|
|
||||||
|
|
||||||
bool shallow_mod = arg_get_lit(ctx, 10);
|
CLIParamStrToBuf(arg_get_str(ctx, 10), (uint8_t *)format, sizeof(format), &format_len);
|
||||||
bool verbose = arg_get_lit(ctx, 11);
|
|
||||||
|
bool shallow_mod = arg_get_lit(ctx, 12);
|
||||||
|
bool verbose = arg_get_lit(ctx, 13);
|
||||||
|
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
|
@ -4669,7 +4685,12 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_enc_key == false) {
|
if (have_enc_key == false) {
|
||||||
|
// The IsCardHelperPresent function clears the emulator memory
|
||||||
|
if (use_emulator_memory) {
|
||||||
|
use_sc = false;
|
||||||
|
} else {
|
||||||
use_sc = IsCardHelperPresent(false);
|
use_sc = IsCardHelperPresent(false);
|
||||||
|
}
|
||||||
if (use_sc == false) {
|
if (use_sc == false) {
|
||||||
size_t keylen = 0;
|
size_t keylen = 0;
|
||||||
int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&enckeyptr, &keylen);
|
int res = loadFile_safe(ICLASS_DECRYPTION_BIN, "", (void **)&enckeyptr, &keylen);
|
||||||
|
@ -4774,6 +4795,12 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
|
|
||||||
int isok = PM3_SUCCESS;
|
int isok = PM3_SUCCESS;
|
||||||
// write
|
// write
|
||||||
|
if (use_emulator_memory) {
|
||||||
|
uint16_t byte_sent = 0;
|
||||||
|
iclass_upload_emul(credential, sizeof(credential), 6 * PICOPASS_BLOCK_SIZE, &byte_sent);
|
||||||
|
PrintAndLogEx(SUCCESS, "uploaded " _YELLOW_("%d") " bytes to emulator memory", byte_sent);
|
||||||
|
PrintAndLogEx(HINT, "You are now ready to simulate. See " _YELLOW_("`hf iclass sim -h`"));
|
||||||
|
} else {
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth, shallow_mod);
|
isok = iclass_write_block(6 + i, credential + (i * 8), NULL, key, use_credit_key, elite, rawkey, false, false, auth, shallow_mod);
|
||||||
switch (isok) {
|
switch (isok) {
|
||||||
|
@ -4785,6 +4812,7 @@ static int CmdHFiClassEncode(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return isok;
|
return isok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4962,7 +4990,7 @@ static int CmdHFiClassSAM(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "Wiegand decode");
|
PrintAndLogEx(INFO, "Wiegand decode");
|
||||||
wiegand_message_t packed = initialize_message_object(top, mid, bot, 0);
|
wiegand_message_t packed = initialize_message_object(top, mid, bot, strlen(binstr));
|
||||||
HIDTryUnpack(&packed);
|
HIDTryUnpack(&packed);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
|
@ -9512,9 +9512,9 @@ static int CmdHF14AMfInfo(const char *Cmd) {
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t blockdata[MFBLOCK_SIZE] = {0};
|
||||||
res = mfCheckKeys_fast(sectorsCnt, true, true, 1, keycnt, keyBlock, e_sector, false, verbose);
|
res = mfCheckKeys_fast(sectorsCnt, true, true, 1, keycnt, keyBlock, e_sector, false, verbose);
|
||||||
if (res == PM3_SUCCESS || res == PM3_EPARTIAL) {
|
if (res == PM3_SUCCESS || res == PM3_EPARTIAL) {
|
||||||
uint8_t blockdata[MFBLOCK_SIZE] = {0};
|
|
||||||
|
|
||||||
if (e_sector[0].foundKey[MF_KEY_A]) {
|
if (e_sector[0].foundKey[MF_KEY_A]) {
|
||||||
PrintAndLogEx(SUCCESS, "Sector 0 key A... " _GREEN_("%012" PRIX64), e_sector[0].Key[MF_KEY_A]);
|
PrintAndLogEx(SUCCESS, "Sector 0 key A... " _GREEN_("%012" PRIX64), e_sector[0].Key[MF_KEY_A]);
|
||||||
|
@ -9539,20 +9539,59 @@ static int CmdHF14AMfInfo(const char *Cmd) {
|
||||||
if (e_sector[1].foundKey[MF_KEY_A]) {
|
if (e_sector[1].foundKey[MF_KEY_A]) {
|
||||||
PrintAndLogEx(SUCCESS, "Sector 1 key A... " _GREEN_("%012" PRIX64), e_sector[1].Key[MF_KEY_A]);
|
PrintAndLogEx(SUCCESS, "Sector 1 key A... " _GREEN_("%012" PRIX64), e_sector[1].Key[MF_KEY_A]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t k08s[6] = {0xA3, 0x96, 0xEF, 0xA4, 0xE2, 0x4F};
|
||||||
|
if (mfReadBlock(0, 4, k08s, blockdata) == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Backdoor key..... " _RED_("%02X%02X%02X%02X%02X%02X"), k08s[0], k08s[1], k08s[2], k08s[3], k08s[4], k08s[5]);
|
||||||
|
fKeyType = MF_KEY_BD08S;
|
||||||
|
}
|
||||||
|
uint8_t k08[6] = {0xA3, 0x16, 0x67, 0xA8, 0xCE, 0xC1};
|
||||||
|
if (mfReadBlock(0, 4, k08, blockdata) == PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Backdoor key..... " _RED_("%02X%02X%02X%02X%02X%02X"), k08[0], k08[1], k08[2], k08[3], k08[4], k08[5]);
|
||||||
|
fKeyType = MF_KEY_BD08;
|
||||||
|
}
|
||||||
|
|
||||||
if (fKeyType != 0xFF) {
|
if (fKeyType != 0xFF) {
|
||||||
PrintAndLogEx(SUCCESS, "Block 0.......... %s", sprint_hex(blockdata, MFBLOCK_SIZE));
|
PrintAndLogEx(SUCCESS, "Block 0.......... %s", sprint_hex(blockdata, MFBLOCK_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint"));
|
PrintAndLogEx(INFO, "--- " _CYAN_("Fingerprint"));
|
||||||
if (
|
|
||||||
(blockdata[8] == 0x03 && blockdata[15] == 0x90) ||
|
if (fKeyType != 0xFF) {
|
||||||
(blockdata[9] == 0x02 && blockdata[14] == 0x1D) ||
|
// cards with known backdoor
|
||||||
(blockdata[8] == 0x04 && blockdata[15] == 0x90) ||
|
if (memcmp(blockdata + 8, "\x62\x63\x64\x65\x66\x67\x68\x69", 8) == 0) {
|
||||||
(memcmp(blockdata + 8, "\x62\x63\x64\x65\x66\x67\x68\x69", 8) == 0)
|
// backdoor might be present, or just a clone reusing Fudan MF data...
|
||||||
) {
|
PrintAndLogEx(SUCCESS, "Fudan based card");
|
||||||
PrintAndLogEx(SUCCESS, "FUDAN based card");
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x08\x04\x00", 3) == 0
|
||||||
|
&& (blockdata[8] == 0x03 || blockdata[8] == 0x04) && blockdata[15] == 0x90) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Fudan FM11RF08S");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x00\x03\x00\x10", 4) == 0
|
||||||
|
&& blockdata[15] == 0x90) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Fudan FM11RF08S-7B");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x08\x04\x00", 3) == 0
|
||||||
|
&& (blockdata[8] >= 0x01 && blockdata[8] <= 0x03) && blockdata[15] == 0x1D) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Fudan FM11RF08");
|
||||||
|
} else if (card.sak == 0x88 && memcmp(blockdata + 5, "\x88\x04\x00\x43", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Infineon SLE66R35");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x88\x04\x00\x44", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS5003");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x88\x04\x00\x45", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS5004");
|
||||||
|
} else if (fKeyType == MF_KEY_BD08 || fKeyType == MF_KEY_BD08S) {
|
||||||
|
PrintAndLogEx(SUCCESS, _RED_("Unknown card with backdoor, please report details!"));
|
||||||
|
}
|
||||||
|
// other cards
|
||||||
|
if (card.sak == 0x08 && memcmp(blockdata + 5, "\x88\x04\x00\x46", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS5005");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x88\x04\x00\x47", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS5006");
|
||||||
|
} else if (card.sak == 0x09 && memcmp(blockdata + 5, "\x89\x04\x00\x47", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS2006");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x88\x04\x00\x48", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS5007");
|
||||||
|
} else if (card.sak == 0x08 && memcmp(blockdata + 5, "\x88\x04\x00\xc0", 4) == 0) {
|
||||||
|
PrintAndLogEx(SUCCESS, "NXP MF1ICS5035");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e_sector[1].foundKey[MF_KEY_A] && (e_sector[1].Key[MF_KEY_A] == 0x2A2C13CC242A)) {
|
if (e_sector[1].foundKey[MF_KEY_A] && (e_sector[1].Key[MF_KEY_A] == 0x2A2C13CC242A)) {
|
||||||
|
|
|
@ -53,18 +53,32 @@ void pm3_close(pm3_device_t *dev) {
|
||||||
msleep(100); // Make sure command is sent before killing client
|
msleep(100); // Make sure command is sent before killing client
|
||||||
CloseProxmark(dev);
|
CloseProxmark(dev);
|
||||||
}
|
}
|
||||||
|
free_grabber();
|
||||||
}
|
}
|
||||||
|
|
||||||
int pm3_console(pm3_device_t *dev, const char *cmd) {
|
int pm3_console(pm3_device_t *dev, const char *cmd, bool passthru) {
|
||||||
// For now, there is no real device context:
|
// For now, there is no real device context:
|
||||||
(void) dev;
|
(void) dev;
|
||||||
return CommandReceived(cmd);
|
uint8_t prev_printAndLog = g_printAndLog;
|
||||||
|
if (! passthru) {
|
||||||
|
g_printAndLog |= PRINTANDLOG_GRAB;
|
||||||
|
g_printAndLog &= ~PRINTANDLOG_PRINT;
|
||||||
|
}
|
||||||
|
int ret = CommandReceived(cmd);
|
||||||
|
g_printAndLog = prev_printAndLog;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *pm3_name_get(pm3_device_t *dev) {
|
const char *pm3_name_get(pm3_device_t *dev) {
|
||||||
return dev->g_conn->serial_port_name;
|
return dev->g_conn->serial_port_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *pm3_grabbed_output_get(pm3_device_t *dev) {
|
||||||
|
char *tmp = g_grabbed_output.ptr;
|
||||||
|
g_grabbed_output.idx = 0;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
pm3_device_t *pm3_get_current_dev(void) {
|
pm3_device_t *pm3_get_current_dev(void) {
|
||||||
return g_session.current_device;
|
return g_session.current_device;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,13 @@
|
||||||
/* Strip "pm3_" from API functions for SWIG */
|
/* Strip "pm3_" from API functions for SWIG */
|
||||||
%rename("%(strip:[pm3_])s") "";
|
%rename("%(strip:[pm3_])s") "";
|
||||||
%feature("immutable","1") pm3_current_dev;
|
%feature("immutable","1") pm3_current_dev;
|
||||||
|
|
||||||
|
#ifdef PYWRAP
|
||||||
|
#include <Python.h>
|
||||||
|
%typemap(default) bool passthru {
|
||||||
|
$1 = Py_False;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
typedef struct {
|
typedef struct {
|
||||||
%extend {
|
%extend {
|
||||||
pm3() {
|
pm3() {
|
||||||
|
@ -30,8 +37,9 @@ typedef struct {
|
||||||
pm3_close($self);
|
pm3_close($self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int console(char *cmd);
|
int console(char *cmd, bool passthru = false);
|
||||||
char const * const name;
|
char const * const name;
|
||||||
|
char const * const grabbed_output;
|
||||||
}
|
}
|
||||||
} pm3;
|
} pm3;
|
||||||
//%nodefaultctor device;
|
//%nodefaultctor device;
|
||||||
|
|
|
@ -2768,18 +2768,23 @@ static int _wrap_pm3_console(lua_State *L) {
|
||||||
int SWIG_arg = 0;
|
int SWIG_arg = 0;
|
||||||
pm3 *arg1 = (pm3 *) 0 ;
|
pm3 *arg1 = (pm3 *) 0 ;
|
||||||
char *arg2 = (char *) 0 ;
|
char *arg2 = (char *) 0 ;
|
||||||
|
bool arg3 = (bool) false ;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
SWIG_check_num_args("pm3::console", 2, 2)
|
SWIG_check_num_args("pm3::console", 2, 3)
|
||||||
if (!SWIG_isptrtype(L, 1)) SWIG_fail_arg("pm3::console", 1, "pm3 *");
|
if (!SWIG_isptrtype(L, 1)) SWIG_fail_arg("pm3::console", 1, "pm3 *");
|
||||||
if (!SWIG_lua_isnilstring(L, 2)) SWIG_fail_arg("pm3::console", 2, "char *");
|
if (!SWIG_lua_isnilstring(L, 2)) SWIG_fail_arg("pm3::console", 2, "char *");
|
||||||
|
if (lua_gettop(L) >= 3 && !lua_isboolean(L, 3)) SWIG_fail_arg("pm3::console", 3, "bool");
|
||||||
|
|
||||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L, 1, (void **)&arg1, SWIGTYPE_p_pm3, 0))) {
|
if (!SWIG_IsOK(SWIG_ConvertPtr(L, 1, (void **)&arg1, SWIGTYPE_p_pm3, 0))) {
|
||||||
SWIG_fail_ptr("pm3_console", 1, SWIGTYPE_p_pm3);
|
SWIG_fail_ptr("pm3_console", 1, SWIGTYPE_p_pm3);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg2 = (char *)lua_tostring(L, 2);
|
arg2 = (char *)lua_tostring(L, 2);
|
||||||
result = (int)pm3_console(arg1, arg2);
|
if (lua_gettop(L) >= 3) {
|
||||||
|
arg3 = (lua_toboolean(L, 3) != 0);
|
||||||
|
}
|
||||||
|
result = (int)pm3_console(arg1, arg2, arg3);
|
||||||
lua_pushnumber(L, (lua_Number) result);
|
lua_pushnumber(L, (lua_Number) result);
|
||||||
SWIG_arg++;
|
SWIG_arg++;
|
||||||
return SWIG_arg;
|
return SWIG_arg;
|
||||||
|
@ -2815,6 +2820,30 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int _wrap_pm3_grabbed_output_get(lua_State *L) {
|
||||||
|
int SWIG_arg = 0;
|
||||||
|
pm3 *arg1 = (pm3 *) 0 ;
|
||||||
|
char *result = 0 ;
|
||||||
|
|
||||||
|
SWIG_check_num_args("pm3::grabbed_output", 1, 1)
|
||||||
|
if (!SWIG_isptrtype(L, 1)) SWIG_fail_arg("pm3::grabbed_output", 1, "pm3 *");
|
||||||
|
|
||||||
|
if (!SWIG_IsOK(SWIG_ConvertPtr(L, 1, (void **)&arg1, SWIGTYPE_p_pm3, 0))) {
|
||||||
|
SWIG_fail_ptr("pm3_grabbed_output_get", 1, SWIGTYPE_p_pm3);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = (char *)pm3_grabbed_output_get(arg1);
|
||||||
|
lua_pushstring(L, (const char *)result);
|
||||||
|
SWIG_arg++;
|
||||||
|
return SWIG_arg;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
SWIGUNUSED;
|
||||||
|
lua_error(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void swig_delete_pm3(void *obj) {
|
static void swig_delete_pm3(void *obj) {
|
||||||
pm3 *arg1 = (pm3 *) obj;
|
pm3 *arg1 = (pm3 *) obj;
|
||||||
delete_pm3(arg1);
|
delete_pm3(arg1);
|
||||||
|
@ -2829,6 +2858,7 @@ static int _proxy__wrap_new_pm3(lua_State *L) {
|
||||||
}
|
}
|
||||||
static swig_lua_attribute swig_pm3_attributes[] = {
|
static swig_lua_attribute swig_pm3_attributes[] = {
|
||||||
{ "name", _wrap_pm3_name_get, SWIG_Lua_set_immutable },
|
{ "name", _wrap_pm3_name_get, SWIG_Lua_set_immutable },
|
||||||
|
{ "grabbed_output", _wrap_pm3_grabbed_output_get, SWIG_Lua_set_immutable },
|
||||||
{0, 0, 0}
|
{0, 0, 0}
|
||||||
};
|
};
|
||||||
static swig_lua_method swig_pm3_methods[] = {
|
static swig_lua_method swig_pm3_methods[] = {
|
||||||
|
|
|
@ -3270,6 +3270,149 @@ SWIGINTERN void delete_pm3(pm3 *self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SWIGINTERN int
|
||||||
|
SWIG_AsVal_double(PyObject *obj, double *val) {
|
||||||
|
int res = SWIG_TypeError;
|
||||||
|
if (PyFloat_Check(obj)) {
|
||||||
|
if (val) *val = PyFloat_AsDouble(obj);
|
||||||
|
return SWIG_OK;
|
||||||
|
#if PY_VERSION_HEX < 0x03000000
|
||||||
|
} else if (PyInt_Check(obj)) {
|
||||||
|
if (val) *val = (double) PyInt_AsLong(obj);
|
||||||
|
return SWIG_OK;
|
||||||
|
#endif
|
||||||
|
} else if (PyLong_Check(obj)) {
|
||||||
|
double v = PyLong_AsDouble(obj);
|
||||||
|
if (!PyErr_Occurred()) {
|
||||||
|
if (val) *val = v;
|
||||||
|
return SWIG_OK;
|
||||||
|
} else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef SWIG_PYTHON_CAST_MODE
|
||||||
|
{
|
||||||
|
int dispatch = 0;
|
||||||
|
double d = PyFloat_AsDouble(obj);
|
||||||
|
if (!PyErr_Occurred()) {
|
||||||
|
if (val) *val = d;
|
||||||
|
return SWIG_AddCast(SWIG_OK);
|
||||||
|
} else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
if (!dispatch) {
|
||||||
|
long v = PyLong_AsLong(obj);
|
||||||
|
if (!PyErr_Occurred()) {
|
||||||
|
if (val) *val = v;
|
||||||
|
return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
|
||||||
|
} else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERNINLINE int
|
||||||
|
SWIG_CanCastAsInteger(double *d, double min, double max) {
|
||||||
|
double x = *d;
|
||||||
|
if ((min <= x && x <= max)) {
|
||||||
|
double fx, cx, rd;
|
||||||
|
errno = 0;
|
||||||
|
fx = floor(x);
|
||||||
|
cx = ceil(x);
|
||||||
|
rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */
|
||||||
|
if ((errno == EDOM) || (errno == ERANGE)) {
|
||||||
|
errno = 0;
|
||||||
|
} else {
|
||||||
|
double summ, reps, diff;
|
||||||
|
if (rd < x) {
|
||||||
|
diff = x - rd;
|
||||||
|
} else if (rd > x) {
|
||||||
|
diff = rd - x;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
summ = rd + x;
|
||||||
|
reps = diff / summ;
|
||||||
|
if (reps < 8 * DBL_EPSILON) {
|
||||||
|
*d = rd;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN int
|
||||||
|
SWIG_AsVal_long(PyObject *obj, long *val) {
|
||||||
|
#if PY_VERSION_HEX < 0x03000000
|
||||||
|
if (PyInt_Check(obj)) {
|
||||||
|
if (val) *val = PyInt_AsLong(obj);
|
||||||
|
return SWIG_OK;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
if (PyLong_Check(obj)) {
|
||||||
|
long v = PyLong_AsLong(obj);
|
||||||
|
if (!PyErr_Occurred()) {
|
||||||
|
if (val) *val = v;
|
||||||
|
return SWIG_OK;
|
||||||
|
} else {
|
||||||
|
PyErr_Clear();
|
||||||
|
return SWIG_OverflowError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef SWIG_PYTHON_CAST_MODE
|
||||||
|
{
|
||||||
|
int dispatch = 0;
|
||||||
|
long v = PyInt_AsLong(obj);
|
||||||
|
if (!PyErr_Occurred()) {
|
||||||
|
if (val) *val = v;
|
||||||
|
return SWIG_AddCast(SWIG_OK);
|
||||||
|
} else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
if (!dispatch) {
|
||||||
|
double d;
|
||||||
|
int res = SWIG_AddCast(SWIG_AsVal_double(obj, &d));
|
||||||
|
// Largest double not larger than LONG_MAX (not portably calculated easily)
|
||||||
|
// Note that double(LONG_MAX) is stored in a double rounded up by one (for 64-bit long)
|
||||||
|
// 0x7ffffffffffffc00LL == (int64_t)std::nextafter(double(__uint128_t(LONG_MAX)+1), double(0))
|
||||||
|
const double long_max = sizeof(long) == 8 ? 0x7ffffffffffffc00LL : LONG_MAX;
|
||||||
|
// No equivalent needed for 64-bit double(LONG_MIN) is exactly LONG_MIN
|
||||||
|
if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, long_max)) {
|
||||||
|
if (val) *val = (long)(d);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return SWIG_TypeError;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN int
|
||||||
|
SWIG_AsVal_bool(PyObject *obj, bool *val) {
|
||||||
|
int r;
|
||||||
|
if (!PyBool_Check(obj))
|
||||||
|
return SWIG_ERROR;
|
||||||
|
r = PyObject_IsTrue(obj);
|
||||||
|
if (r == -1)
|
||||||
|
return SWIG_ERROR;
|
||||||
|
if (val) *val = r ? true : false;
|
||||||
|
return SWIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERNINLINE PyObject *
|
SWIGINTERNINLINE PyObject *
|
||||||
SWIG_From_int(int value) {
|
SWIG_From_int(int value) {
|
||||||
return PyInt_FromLong((long) value);
|
return PyInt_FromLong((long) value);
|
||||||
|
@ -3403,16 +3546,19 @@ SWIGINTERN PyObject *_wrap_pm3_console(PyObject *self, PyObject *args) {
|
||||||
PyObject *resultobj = 0;
|
PyObject *resultobj = 0;
|
||||||
pm3 *arg1 = (pm3 *) 0 ;
|
pm3 *arg1 = (pm3 *) 0 ;
|
||||||
char *arg2 = (char *) 0 ;
|
char *arg2 = (char *) 0 ;
|
||||||
|
bool arg3 = (bool) false ;
|
||||||
void *argp1 = 0 ;
|
void *argp1 = 0 ;
|
||||||
int res1 = 0 ;
|
int res1 = 0 ;
|
||||||
int res2 ;
|
int res2 ;
|
||||||
char *buf2 = 0 ;
|
char *buf2 = 0 ;
|
||||||
int alloc2 = 0 ;
|
int alloc2 = 0 ;
|
||||||
PyObject *swig_obj[2] ;
|
bool val3 ;
|
||||||
|
int ecode3 = 0 ;
|
||||||
|
PyObject *swig_obj[3] ;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
(void)self;
|
(void)self;
|
||||||
if (!SWIG_Python_UnpackTuple(args, "pm3_console", 2, 2, swig_obj)) SWIG_fail;
|
if (!SWIG_Python_UnpackTuple(args, "pm3_console", 2, 3, swig_obj)) SWIG_fail;
|
||||||
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_pm3, 0 | 0);
|
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_pm3, 0 | 0);
|
||||||
if (!SWIG_IsOK(res1)) {
|
if (!SWIG_IsOK(res1)) {
|
||||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_console" "', argument " "1"" of type '" "pm3 *""'");
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_console" "', argument " "1"" of type '" "pm3 *""'");
|
||||||
|
@ -3423,7 +3569,14 @@ SWIGINTERN PyObject *_wrap_pm3_console(PyObject *self, PyObject *args) {
|
||||||
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pm3_console" "', argument " "2"" of type '" "char *""'");
|
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pm3_console" "', argument " "2"" of type '" "char *""'");
|
||||||
}
|
}
|
||||||
arg2 = (char *)(buf2);
|
arg2 = (char *)(buf2);
|
||||||
result = (int)pm3_console(arg1, arg2);
|
if (swig_obj[2]) {
|
||||||
|
ecode3 = SWIG_AsVal_bool(swig_obj[2], &val3);
|
||||||
|
if (!SWIG_IsOK(ecode3)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pm3_console" "', argument " "3"" of type '" "bool""'");
|
||||||
|
}
|
||||||
|
arg3 = (bool)(val3);
|
||||||
|
}
|
||||||
|
result = (int)pm3_console(arg1, arg2, arg3);
|
||||||
resultobj = SWIG_From_int((int)(result));
|
resultobj = SWIG_From_int((int)(result));
|
||||||
if (alloc2 == SWIG_NEWOBJ) free((char *)buf2);
|
if (alloc2 == SWIG_NEWOBJ) free((char *)buf2);
|
||||||
return resultobj;
|
return resultobj;
|
||||||
|
@ -3457,6 +3610,30 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SWIGINTERN PyObject *_wrap_pm3_grabbed_output_get(PyObject *self, PyObject *args) {
|
||||||
|
PyObject *resultobj = 0;
|
||||||
|
pm3 *arg1 = (pm3 *) 0 ;
|
||||||
|
void *argp1 = 0 ;
|
||||||
|
int res1 = 0 ;
|
||||||
|
PyObject *swig_obj[1] ;
|
||||||
|
char *result = 0 ;
|
||||||
|
|
||||||
|
(void)self;
|
||||||
|
if (!args) SWIG_fail;
|
||||||
|
swig_obj[0] = args;
|
||||||
|
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_pm3, 0 | 0);
|
||||||
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_grabbed_output_get" "', argument " "1"" of type '" "pm3 *""'");
|
||||||
|
}
|
||||||
|
arg1 = (pm3 *)(argp1);
|
||||||
|
result = (char *)pm3_grabbed_output_get(arg1);
|
||||||
|
resultobj = SWIG_FromCharPtr((const char *)result);
|
||||||
|
return resultobj;
|
||||||
|
fail:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SWIGINTERN PyObject *pm3_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
SWIGINTERN PyObject *pm3_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||||
PyObject *obj;
|
PyObject *obj;
|
||||||
if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
|
if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
|
||||||
|
@ -3473,6 +3650,7 @@ static PyMethodDef SwigMethods[] = {
|
||||||
{ "delete_pm3", _wrap_delete_pm3, METH_O, NULL},
|
{ "delete_pm3", _wrap_delete_pm3, METH_O, NULL},
|
||||||
{ "pm3_console", _wrap_pm3_console, METH_VARARGS, NULL},
|
{ "pm3_console", _wrap_pm3_console, METH_VARARGS, NULL},
|
||||||
{ "pm3_name_get", _wrap_pm3_name_get, METH_O, NULL},
|
{ "pm3_name_get", _wrap_pm3_name_get, METH_O, NULL},
|
||||||
|
{ "pm3_grabbed_output_get", _wrap_pm3_grabbed_output_get, METH_O, NULL},
|
||||||
{ "pm3_swigregister", pm3_swigregister, METH_O, NULL},
|
{ "pm3_swigregister", pm3_swigregister, METH_O, NULL},
|
||||||
{ "pm3_swiginit", pm3_swiginit, METH_VARARGS, NULL},
|
{ "pm3_swiginit", pm3_swiginit, METH_VARARGS, NULL},
|
||||||
{ NULL, NULL, 0, NULL }
|
{ NULL, NULL, 0, NULL }
|
||||||
|
|
|
@ -553,7 +553,7 @@ check_script:
|
||||||
if (cmd[0] != '\0') {
|
if (cmd[0] != '\0') {
|
||||||
uint8_t old_printAndLog = g_printAndLog;
|
uint8_t old_printAndLog = g_printAndLog;
|
||||||
if (!printprompt) {
|
if (!printprompt) {
|
||||||
g_printAndLog &= PRINTANDLOG_LOG;
|
g_printAndLog &= ~PRINTANDLOG_PRINT;
|
||||||
}
|
}
|
||||||
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
||||||
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev, prompt_net, true);
|
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev, prompt_net, true);
|
||||||
|
@ -1462,6 +1462,8 @@ int main(int argc, char *argv[]) {
|
||||||
preferences_save();
|
preferences_save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_grabber();
|
||||||
|
|
||||||
return mainret;
|
return mainret;
|
||||||
}
|
}
|
||||||
#endif //LIBPM3
|
#endif //LIBPM3
|
||||||
|
|
|
@ -360,7 +360,7 @@ serial_port uart_open(const char *pcPortName, uint32_t speed, bool slient) {
|
||||||
free(prefix);
|
free(prefix);
|
||||||
|
|
||||||
// Freshly available port can take a while before getting permission to access it. Up to 600ms on my machine...
|
// Freshly available port can take a while before getting permission to access it. Up to 600ms on my machine...
|
||||||
for (uint8_t i =0; i < 10; i++) {
|
for (uint8_t i = 0; i < 10; i++) {
|
||||||
sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
|
sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
|
||||||
if (sp->fd != -1 || errno != EACCES)
|
if (sp->fd != -1 || errno != EACCES)
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -168,6 +168,33 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_grabber(void) {
|
||||||
|
free(g_grabbed_output.ptr);
|
||||||
|
g_grabbed_output.ptr = NULL;
|
||||||
|
g_grabbed_output.size = 0;
|
||||||
|
g_grabbed_output.idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_grabber(const char *string) {
|
||||||
|
if (g_grabbed_output.ptr == NULL || g_grabbed_output.size - g_grabbed_output.idx < MAX_PRINT_BUFFER) {
|
||||||
|
char *tmp = realloc(g_grabbed_output.ptr, g_grabbed_output.size + MAX_PRINT_BUFFER);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
// We leave current g_grabbed_output untouched
|
||||||
|
PrintAndLogEx(ERR, "Out of memory error in fill_grabber()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_grabbed_output.ptr = tmp;
|
||||||
|
g_grabbed_output.size += MAX_PRINT_BUFFER;
|
||||||
|
}
|
||||||
|
int len = snprintf(g_grabbed_output.ptr + g_grabbed_output.idx, MAX_PRINT_BUFFER, "%s", string);
|
||||||
|
if (len < 0 || len > MAX_PRINT_BUFFER) {
|
||||||
|
// We leave current g_grabbed_output_len untouched
|
||||||
|
PrintAndLogEx(ERR, "snprintf error in fill_grabber()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_grabbed_output.idx += len;
|
||||||
|
}
|
||||||
|
|
||||||
void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) {
|
void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) {
|
||||||
char buff[2000] = "Options:\n";
|
char buff[2000] = "Options:\n";
|
||||||
char format[2000] = "";
|
char format[2000] = "";
|
||||||
|
@ -299,12 +326,15 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) {
|
||||||
} else {
|
} else {
|
||||||
snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer);
|
snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer);
|
||||||
if (level == INPLACE) {
|
if (level == INPLACE) {
|
||||||
|
// ignore INPLACE if rest of output is grabbed
|
||||||
|
if (!(g_printAndLog & PRINTANDLOG_GRAB)) {
|
||||||
char buffer3[sizeof(buffer2)] = {0};
|
char buffer3[sizeof(buffer2)] = {0};
|
||||||
char buffer4[sizeof(buffer2)] = {0};
|
char buffer4[sizeof(buffer2)] = {0};
|
||||||
memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !g_session.supports_colors);
|
memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !g_session.supports_colors);
|
||||||
memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), g_session.emoji_mode);
|
memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), g_session.emoji_mode);
|
||||||
fprintf(stream, "\r%s", buffer4);
|
fprintf(stream, "\r%s", buffer4);
|
||||||
fflush(stream);
|
fflush(stream);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fPrintAndLog(stream, "%s", buffer2);
|
fPrintAndLog(stream, "%s", buffer2);
|
||||||
}
|
}
|
||||||
|
@ -401,18 +431,32 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) {
|
if (((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) ||
|
||||||
|
(g_printAndLog & PRINTANDLOG_GRAB)) {
|
||||||
memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), EMO_ALTTEXT);
|
memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), EMO_ALTTEXT);
|
||||||
if (filter_ansi) { // already done
|
if (!filter_ansi) {
|
||||||
|
memcpy_filter_ansi(buffer, buffer3, sizeof(buffer3), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) {
|
||||||
|
if (filter_ansi) {
|
||||||
fprintf(logfile, "%s", buffer3);
|
fprintf(logfile, "%s", buffer3);
|
||||||
} else {
|
} else {
|
||||||
memcpy_filter_ansi(buffer, buffer3, sizeof(buffer3), true);
|
|
||||||
fprintf(logfile, "%s", buffer);
|
fprintf(logfile, "%s", buffer);
|
||||||
}
|
}
|
||||||
if (linefeed)
|
if (linefeed)
|
||||||
fprintf(logfile, "\n");
|
fprintf(logfile, "\n");
|
||||||
fflush(logfile);
|
fflush(logfile);
|
||||||
}
|
}
|
||||||
|
if (g_printAndLog & PRINTANDLOG_GRAB) {
|
||||||
|
if (filter_ansi) {
|
||||||
|
fill_grabber(buffer3);
|
||||||
|
} else {
|
||||||
|
fill_grabber(buffer);
|
||||||
|
}
|
||||||
|
if (linefeed)
|
||||||
|
fill_grabber("\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (flushAfterWrite)
|
if (flushAfterWrite)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
|
@ -80,6 +80,7 @@ bool GetFlushAfterWrite(void);
|
||||||
void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter);
|
void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter);
|
||||||
void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n);
|
void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n);
|
||||||
void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode);
|
void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode);
|
||||||
|
void free_grabber(void);
|
||||||
|
|
||||||
int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home);
|
int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home);
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,10 @@
|
||||||
#define UTIL_BUFFER_SIZE_SPRINT 8196
|
#define UTIL_BUFFER_SIZE_SPRINT 8196
|
||||||
// global client debug variable
|
// global client debug variable
|
||||||
uint8_t g_debugMode = 0;
|
uint8_t g_debugMode = 0;
|
||||||
// global client disable logging variable
|
// global client enable/disable printing/logging/grabbing variable
|
||||||
uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
||||||
|
// global pointer to grabbed output
|
||||||
|
grabbed_output g_grabbed_output = {NULL, 0, 0};
|
||||||
// global client tell if a pending prompt is present
|
// global client tell if a pending prompt is present
|
||||||
bool g_pendingPrompt = false;
|
bool g_pendingPrompt = false;
|
||||||
// global CPU core count override
|
// global CPU core count override
|
||||||
|
|
|
@ -34,8 +34,16 @@ extern uint8_t g_printAndLog;
|
||||||
extern bool g_pendingPrompt;
|
extern bool g_pendingPrompt;
|
||||||
extern int g_numCPUs;
|
extern int g_numCPUs;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *ptr;
|
||||||
|
size_t size;
|
||||||
|
size_t idx;
|
||||||
|
} grabbed_output;
|
||||||
|
extern grabbed_output g_grabbed_output;
|
||||||
|
|
||||||
#define PRINTANDLOG_PRINT 1
|
#define PRINTANDLOG_PRINT 1
|
||||||
#define PRINTANDLOG_LOG 2
|
#define PRINTANDLOG_LOG 2
|
||||||
|
#define PRINTANDLOG_GRAB 4
|
||||||
|
|
||||||
// Return error
|
// Return error
|
||||||
#define PM3_RET_ERR(err, ...) { \
|
#define PM3_RET_ERR(err, ...) { \
|
||||||
|
|
|
@ -20,6 +20,69 @@
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
|
||||||
|
|
||||||
|
static bool Pack_Defcon32(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) {
|
||||||
|
memset(packed, 0, sizeof(wiegand_message_t));
|
||||||
|
if (card->FacilityCode > 0x00FFFF) return false; // Can't encode FC.
|
||||||
|
if (card->CardNumber > 0x0fffff) return false; // Can't encode CN.
|
||||||
|
if (card->IssueLevel > 0x00000F) return false; // Can't encode Issue
|
||||||
|
if (card->OEM > 0) return false; // Not used in this format
|
||||||
|
|
||||||
|
packed->Length = 42;
|
||||||
|
/*
|
||||||
|
By implementing this format I hope to make the CTF easier for people to get into next year
|
||||||
|
//~~The wiegand data consists of 3 32 bit units that we need to split the data between Bottom and Mid since we have a 42 bit format~~
|
||||||
|
We can use the set linear field function instead this seems to be easier.
|
||||||
|
|Mid part| | Bot part of the packed data |
|
||||||
|
PFFFFFFFFF FFFFFFFIIIICCCCCCCCCCCCCCCCCCCCP
|
||||||
|
1111111111 11111111111000000000000000001000
|
||||||
|
FC 111111111 1111111 = FF FF
|
||||||
|
//FC Mid 111111111 0000000 = FF 80 These where used to split data between bot/mid
|
||||||
|
//FC Bot 000000000 1111111 = 00 7F
|
||||||
|
Issuance 1111 = 0F
|
||||||
|
Card Number 11111111111111111111 = 0FFFFF
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Referenced from MSB
|
||||||
|
set_linear_field(packed, card->CardNumber, 21, 20); // 20 bit
|
||||||
|
set_linear_field(packed, card->IssueLevel, 17, 4); // 4 bit
|
||||||
|
set_linear_field(packed, card->FacilityCode, 1, 16); // 16 bits
|
||||||
|
|
||||||
|
// Parity calc
|
||||||
|
//0123456789|0123456789|0123456789|0123456789|01
|
||||||
|
//E E E E E |E E E E E |EO O O O O| O O O O O| O
|
||||||
|
set_bit_by_position(packed,
|
||||||
|
evenparity32(
|
||||||
|
get_nonlinear_field(packed, 16, (uint8_t[]) {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}))
|
||||||
|
, 0);
|
||||||
|
|
||||||
|
set_bit_by_position(packed,
|
||||||
|
oddparity32(
|
||||||
|
get_nonlinear_field(packed, 16, (uint8_t[]) {21, 23, 25, 27, 29, 31, 33, 35, 37, 39}))
|
||||||
|
, 41);
|
||||||
|
if (preamble)
|
||||||
|
return add_HID_header(packed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Unpack_Defcon32(wiegand_message_t *packed, wiegand_card_t *card) {
|
||||||
|
memset(card, 0, sizeof(wiegand_card_t));
|
||||||
|
|
||||||
|
if (packed->Length != 42) return false; // Wrong length? Stop here.
|
||||||
|
|
||||||
|
card->FacilityCode = get_linear_field(packed, 1, 16);
|
||||||
|
card->IssueLevel = get_linear_field(packed, 17, 4);
|
||||||
|
card->CardNumber = get_linear_field(packed, 21, 20);
|
||||||
|
|
||||||
|
card->ParityValid =
|
||||||
|
(get_bit_by_position(packed, 41) == oddparity32(
|
||||||
|
get_nonlinear_field(packed, 16, (uint8_t[]) {21, 23, 25, 27, 29, 31, 33, 35, 37, 39})))&&
|
||||||
|
(get_bit_by_position(packed, 0) ==
|
||||||
|
evenparity32(get_nonlinear_field(packed, 16, (uint8_t[]) {2, 4, 6, 8, 10, 12, 14, 16, 18, 20})));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) {
|
static bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) {
|
||||||
memset(packed, 0, sizeof(wiegand_message_t));
|
memset(packed, 0, sizeof(wiegand_message_t));
|
||||||
|
|
||||||
|
@ -1474,6 +1537,7 @@ static const cardformat_t FormatTable[] = {
|
||||||
{"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack
|
{"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack
|
||||||
{"BC40", Pack_bc40, Unpack_bc40, "Bundy TimeClock 40-bit", {1, 1, 0, 1, 1}}, // from
|
{"BC40", Pack_bc40, Unpack_bc40, "Bundy TimeClock 40-bit", {1, 1, 0, 1, 1}}, // from
|
||||||
{"Avig56", Pack_Avig56, Unpack_Avig56, "Avigilon 56-bit", {1, 1, 0, 0, 1}},
|
{"Avig56", Pack_Avig56, Unpack_Avig56, "Avigilon 56-bit", {1, 1, 0, 0, 1}},
|
||||||
|
{"Defcon32", Pack_Defcon32, Unpack_Defcon32, "Custom Defcon RFCTF 42 BIT format", {1, 1, 1, 0, 1}}, // Created by (@micsen) for the CTF
|
||||||
{NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array
|
{NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4340,9 +4340,10 @@
|
||||||
"--4k MIFARE Classic 4k / S70",
|
"--4k MIFARE Classic 4k / S70",
|
||||||
"--emu Fill simulator keys from found keys",
|
"--emu Fill simulator keys from found keys",
|
||||||
"--dump Dump found keys to binary file",
|
"--dump Dump found keys to binary file",
|
||||||
"-f, --file <fn> Filename of dictionary"
|
"-f, --file <fn> Filename of dictionary",
|
||||||
|
"--no-default Don't add the bunch of extra default keys"
|
||||||
],
|
],
|
||||||
"usage": "hf mf chk [-hab*] [-k <hex>]... [--tblk <dec>] [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [-f <fn>]"
|
"usage": "hf mf chk [-hab*] [-k <hex>]... [--tblk <dec>] [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [-f <fn>] [--no-default]"
|
||||||
},
|
},
|
||||||
"hf mf cload": {
|
"hf mf cload": {
|
||||||
"command": "hf mf cload",
|
"command": "hf mf cload",
|
||||||
|
@ -4703,9 +4704,10 @@
|
||||||
"-f, --file <fn> filename of dictionary",
|
"-f, --file <fn> filename of dictionary",
|
||||||
"--blk <dec> block number (single block recovery mode)",
|
"--blk <dec> block number (single block recovery mode)",
|
||||||
"-a single block recovery key A",
|
"-a single block recovery key A",
|
||||||
"-b single block recovery key B"
|
"-b single block recovery key B",
|
||||||
|
"--no-default Don't add the bunch of extra default keys"
|
||||||
],
|
],
|
||||||
"usage": "hf mf fchk [-hab] [-k <hex>]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f <fn>] [--blk <dec>]"
|
"usage": "hf mf fchk [-hab] [-k <hex>]... [--mini] [--1k] [--2k] [--4k] [--emu] [--dump] [--mem] [-f <fn>] [--blk <dec>] [--no-default]"
|
||||||
},
|
},
|
||||||
"hf mf gchpwd": {
|
"hf mf gchpwd": {
|
||||||
"command": "hf mf gchpwd",
|
"command": "hf mf gchpwd",
|
||||||
|
@ -5044,13 +5046,14 @@
|
||||||
"--key2 <hex> nested key, 6 hex bytes (default=same)",
|
"--key2 <hex> nested key, 6 hex bytes (default=same)",
|
||||||
"-n <dec> number of nonces (default=2)",
|
"-n <dec> number of nonces (default=2)",
|
||||||
"--reset reset between attempts, even if auth was successful",
|
"--reset reset between attempts, even if auth was successful",
|
||||||
|
"--hardreset hard reset (RF off/on) between attempts, even if auth was successful",
|
||||||
"--addread auth(blk)-read(blk)-auth(blk2)",
|
"--addread auth(blk)-read(blk)-auth(blk2)",
|
||||||
"--addauth auth(blk)-auth(blk)-auth(blk2)",
|
"--addauth auth(blk)-auth(blk)-auth(blk2)",
|
||||||
"--incblk2 auth(blk)-auth(blk2)-auth(blk2+4)-...",
|
"--incblk2 auth(blk)-auth(blk2)-auth(blk2+4)-...",
|
||||||
"--corruptnrar corrupt {nR}{aR}, but with correct parity",
|
"--corruptnrar corrupt {nR}{aR}, but with correct parity",
|
||||||
"--corruptnrarparity correct {nR}{aR}, but with corrupted parity"
|
"--corruptnrarparity correct {nR}{aR}, but with corrupted parity"
|
||||||
],
|
],
|
||||||
"usage": "hf mf isen [-hab] [--blk <dec>] [-c <dec>] [-k <hex>] [--blk2 <dec>] [--a2] [--b2] [--c2 <dec>] [--key2 <hex>] [-n <dec>] [--reset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity]"
|
"usage": "hf mf isen [-hab] [--blk <dec>] [-c <dec>] [-k <hex>] [--blk2 <dec>] [--a2] [--b2] [--c2 <dec>] [--key2 <hex>] [-n <dec>] [--reset] [--hardreset] [--addread] [--addauth] [--incblk2] [--corruptnrar] [--corruptnrarparity]"
|
||||||
},
|
},
|
||||||
"hf mf mad": {
|
"hf mf mad": {
|
||||||
"command": "hf mf mad",
|
"command": "hf mf mad",
|
||||||
|
@ -12810,6 +12813,6 @@
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 740,
|
"commands_extracted": 740,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2024-08-03T19:17:38"
|
"extracted_on": "2024-08-14T11:49:06"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ This is the cheapest and most common ID82xx chip available. It is usually sold a
|
||||||
#### Characteristics
|
#### Characteristics
|
||||||
|
|
||||||
* Chip is likely a Hitag μ (micro)
|
* Chip is likely a Hitag μ (micro)
|
||||||
* Password protection (4b), usually "1AC4999C"
|
* Password protection (4b), usually "00000000"(default) or "9AC4999C"(FURUI)
|
||||||
* Currently unimplemented in proxmark3 client
|
* Currently unimplemented in proxmark3 client
|
||||||
* Other names:
|
* Other names:
|
||||||
* ID8210 (CN)
|
* ID8210 (CN)
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#define MF_KEY_A 0
|
#define MF_KEY_A 0
|
||||||
#define MF_KEY_B 1
|
#define MF_KEY_B 1
|
||||||
|
#define MF_KEY_BD08S 2
|
||||||
|
#define MF_KEY_BD08 3
|
||||||
|
|
||||||
#define MF_MAD1_SECTOR 0x00
|
#define MF_MAD1_SECTOR 0x00
|
||||||
#define MF_MAD2_SECTOR 0x10
|
#define MF_MAD2_SECTOR 0x10
|
||||||
|
|
|
@ -23,8 +23,8 @@ ifneq (,$(findstring MINGW,$(platform)))
|
||||||
CFLAGS += -D_ISOC99_SOURCE
|
CFLAGS += -D_ISOC99_SOURCE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# macOS doesn't like these compiler params
|
# clang doesn't like these compiler params
|
||||||
ifneq ($(platform),Darwin)
|
ifneq ($(DETECTED_COMPILER), clang)
|
||||||
MYCFLAGS += --param max-completely-peeled-insns=1000 --param max-completely-peel-times=10000
|
MYCFLAGS += --param max-completely-peeled-insns=1000 --param max-completely-peel-times=10000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// Strategy:
|
// Strategy:
|
||||||
// * Find all possible key candidates for one reference sector, and check on-the-fly if they are compatible with any other sector we want to compare with
|
// * Find all possible key candidates for one reference sector, and check on-the-fly if they are compatible with any other sector we want to compare with
|
||||||
//
|
//
|
||||||
// Doegox, 2024
|
// Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// * Enumerate key candidates based on clear and encrypted nT
|
// * Enumerate key candidates based on clear and encrypted nT
|
||||||
// * Use the resulting dictionary to bruteforce the key
|
// * Use the resulting dictionary to bruteforce the key
|
||||||
//
|
//
|
||||||
// Doegox, 2024
|
// Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// * Search couples of keyA/keyB satisfying some obscure relationship
|
// * Search couples of keyA/keyB satisfying some obscure relationship
|
||||||
// * Use the resulting dictionary to bruteforce the keyA (and staticnested_2x1nt_rf08s_1key for keyB)
|
// * Use the resulting dictionary to bruteforce the keyA (and staticnested_2x1nt_rf08s_1key for keyB)
|
||||||
//
|
//
|
||||||
// Doegox, 2024
|
// Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
// * Use f08s_nested_known_collision to crack keyA
|
// * Use f08s_nested_known_collision to crack keyA
|
||||||
// * If keyB not readable, find keyB in its dictionary based on the obscure relationship between keyA, keyB and their nT
|
// * If keyB not readable, find keyB in its dictionary based on the obscure relationship between keyA, keyB and their nT
|
||||||
//
|
//
|
||||||
// Doegox, 2024
|
// Doegox, 2024, cf https://eprint.iacr.org/2024/1275 for more info
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
|
@ -21,8 +21,8 @@ ifneq (,$(findstring MINGW,$(platform)))
|
||||||
CFLAGS += -D_ISOC99_SOURCE
|
CFLAGS += -D_ISOC99_SOURCE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# macOS doesn't like these compiler params
|
# clang doesn't like these compiler params
|
||||||
ifneq ($(platform),Darwin)
|
ifneq ($(DETECTED_COMPILER), clang)
|
||||||
MYCFLAGS += --param max-completely-peeled-insns=1000 --param max-completely-peel-times=10000
|
MYCFLAGS += --param max-completely-peeled-insns=1000 --param max-completely-peel-times=10000
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue