Authenticate/Read/Write NFC Mifare Classic Using Private Key - rfid

With refrence to Michael Roland's answer, I am facing problems in changing the key of a Mifare Classic 4K card. I want to do the personalization of NFC cards using NFC reader ACR122U.
I have followed the steps defined in this answer, and successfully read and write the sector trailer block 11 (by reading I got the 2 access bytes and 1 general purpose byte), as
00 00 00 00 00 7F 07 88 40 00 00 00 00 00
Using these access bytes and the new keys KeyA (D6 DF 20 AE AE BC) and KeyB (D6 DF 20 AE AE BC), I generate 16 byte (D6 DF 20 AE AE BC ...), along with access bytes to change the sector keys. I.e. write to block 11 with following 16 bytes:
D6 DF 20 AE AE BC 7F 07 88 40 D6 DF 20 AE AE BC
The write command thus becomes
FF D6 00 11 10 D6 DF 20 AE AE BC 7F 07 88 40 D6 DF 20 AE AE BC
The command executed successfully but when I authenticated block 8 (1st block of same sector), using Key B (0x61) and key (1 or 0), the authentication failed and returns 0x63. Which means sector 2 becomes inaccessible.
Also after then read and write to that sector failed.
Also Android App NFCTagInfo shows following
Data (US-ASCII), Shows Sector 2: Read Failed!
Access Conditions : Sector 2 (Could not read access conditions!)

Related

Why I fail to delete or replace inserted Receipt Key with KeyVersion=0x70 in the Javacard?

I have a clean Kona112 Javacard and I'm going to a put a Receipt key into it and then I want to delete it from the card or replace its value.
Step 1: I tried to create a new key on the card with Key Version == 0x71 (Quoted from GP UICC Configuration v1.0.1: "Key Version number '71' with Key Identifier '01' is reserved for the Receipt Key, which is a DES key"):
[Select ISD]
[Successful Mutual Authentication]
--> 84 D8 00 01 1F 71 80 10 B5 75 C3 8D 89 DC F9 B1 74 CC 1E 93 C4 45 C8 2C 03 CD 80 0F EC EA 8D 6F 8F BF 7D D0 // PUT KEY
<-- 6A 80
==> Quoted from GP UICC Configuration v1.0.1: "6A80 = ISO compliant standard status word for Algorithm not supported"
Step 2: As I received "Algorithm not supported" error, I enabled Delegated Management on my card and retried step #1:
[Select ISD]
[Successful Mutual Authentication]
[Proprietary APDU command to enable Delegated Management]
--> 84 D8 00 01 1F 71 80 10 1A F6 96 45 2A ED 66 86 75 DF FC 8B 59 55 6D 0B 03 CD 80 0F 87 03 E4 1A 8D AB 90 EC
<-- 71 CD 80 0F 90 00
Good! I successfully put the Receipt key in the card.
Step 3: Now, I want to delete it:
[Select ISD]
[Successful Mutual Authentication]
--> 80 E4 00 00 06 D0 01 01 D2 01 71 // Delete APDU Command to delete a key with Key ID = 01 and Key Version = 71
<-- 6A 80
As you see above, I received 6A 80 error status words. It is mentioned in the answer of my other question (and also in GP UICC Configuration v1.0.1) that the Key Deletion feature is optional.
So in step #4 I tried to replace the key with another value.
Step 4: I changed P1 in PUT Key APDU command from 0x00 (create key) to 0x71 (overwrite):
[Select ISD]
[Successful Mutual Authentication]
--> 84 D8 71 01 1F 71 80 10 E9 06 6B 8E D8 05 50 34 D5 A7 71 3B 81 CB BE 7A 03 CD 80 0F 91 0D BC E9 96 25 7E 89
<-- 6A 88
==> Quoted from GP UICC Configuration v1.0.1: "6A88 = Referenced data not found"
Well, that's weird, I received "Referenced data not found". So I tried the PUT Key command with P1 = 0X00 (Create Key) again:
[Select ISD]
[Successful Mutual Authentication]
--> 84 D8 00 01 1F 71 80 10 31 35 5C 0C E3 27 FD D5 8B 6B AE 37 56 CA 0D F2 03 CD 80 0F 0B EB 16 CF FF CE 4C 09
<-- 69 85 // Conditions of used not satisfied.
Well, I tried both cases of step #3 (P1 = 0x00 and P1 = 0x71) with disabled Delegated Management too, but nothing changed and I respectively received 0x6A80 and 0x6A88.
What's wrong? How can I fix the delete or modify this key?
Note that I tried all the steps in secure channel with SecurityLevel = 0x03 too. Nothing changed.
Update:
I tried to list the available keys in the card using GET DATA APDU command with Key Info Template tag, but I only can see ISD ENC, MAC and KEK keys in the APDU Response (For both DM enabled and DM Disabled.
--> 80 CA 00 E0 00
<-- E0 12 C0 04 01 01 80 10 C0 04 02 01 80 10 C0 04 03 01 80 10 90 00
One idea: The receipt key (and you also have to store a token key) might be linked to a application security domain. Select the Security Domain with Token Verification privilege and the Security Domain with Receipt Generation
privilege, maybe they are different from the ISD. I assume also that during [Proprietary APDU command to enable Delegated Management] a new application security domain (ASP) was created. Try the select these new security domains and list there all the keys using the key template flag and execute then your PUT KEY operations against one of these security domains. GET STATUSis the command to be used for listing the SDs. All the existing OS tools like GPShell and GlobalPlatformPro can do this.

How to write bootloader for Oracle virtual box HDD format (VDI files) [duplicate]

There are a lot of question on stackoverflow with the similar title. I read all of them, but none of them answers my problem. This is why I opened this question.
I am creating an operating system in assembler and C. I found that I must compile C code to binary format, extract text section and save it as a file, then convert it to ISO, then mount it to virtual optical dive of diskete and then load my OS in VirtualBox. So, that is a lot of work I want to avoid. I don't want to convert my binary file to ISO every time.
So, I decided to put the binary machine code of my OS to virtual hard drive (VDI file) and then set it to the top of boot order and load it instead of loading from virtual optical drive ISO.
I was researching how VDI works and I found that it is usually dinamically allocated and that only the beginning of data is stored. So, the start of VDI represents a header and the the rest is actual data stored on virtual drive. So, I found that data starts at some address (in my case it is 0x00200000 from the start of the VDI file).
Then, I basically filled from that address to the end of VDI file with pattern 55 AA. So, I suppose it now means that the disk is bootable (because at the end of first sector is still signature 55 AA).
I started virtual machine and it says:
No bootable medium found! System halted
Is there any way to solve this? Why is my virtual disk still not bootable?
Edit
Here is actual VDI file: 1.vdi
You don't provide a minimal complete verifiable example showing a bootloader and how you get it into a VDI. But at a minimum you'll need to place 0xAA55 in the last 2 bytes of the master boot record. The example below creates a simple bootloader; creates a 2MiB raw image; places the bootloader in the raw image; and converts the raw image to a VDI.
boot.asm:
BITS 16
ORG 0x7C00
xor ax, ax
mov ds, ax
mov ss, ax ; Stack below bootloader
mov sp, 0x7c00
mov ax, 0xb800 ; Video segment b800
mov es, ax
; Print Hello with white on light magenta
mov word [es:0x0], 0x57 << 8 | 'H'
mov word [es:0x2], 0x57 << 8 | 'e'
mov word [es:0x4], 0x57 << 8 | 'l'
mov word [es:0x6], 0x57 << 8 | 'l'
mov word [es:0x8], 0x57 << 8 | 'o'
; End with infinite loop
cli
endloop:
hlt
jmp endloop
; Fill out to 510 bytes and add boot signature
times 510 - ($ - $$) db 0
dw 0xAA55 ; add boot signature at the end of bootloader
I then use this command to create the bootloader file boot.bin:
nasm -f bin boot.asm -o boot.bin
Create a 2MiB disk image file 1.raw:
dd if=/dev/zero of=1.raw bs=1024 count=2048
Place the bootloader boot.bin at beginning of file 1.raw without truncating the rest of file:
dd if=boot.bin of=1.raw conv=notrunc
Create a VDI image called 1.vdi from 1.raw:
rm -f 1.vdi
VBoxManage convertfromraw 1.raw 1.vdi --format VDI
When added to a virtual machine under VirtualBox I get this on the display:
Your VDI File
In your supplied image file 1.vdi I noticed this when I did a hexdump:
00200000 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
*
002004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00300000
This output suggests to me that you reversed the bytes of the boot signature in your file. It should be 0x55 followed by 0xaa. 0xaa55 as a WORD is stored with the bytes reversed.
Valid boot medium may be more than just getting the boot signature correct. Some BIOSes may search for certain instructions in the first few bytes that are typically found in bootloaders. Failure to find such instructions (examples often include things like JMP, XOR, CLI, MOV) may cause it to think that it isn't valid boot medium.
One way to test whether 0xAA55 at the end is enough by itself I used hexedit and modified your 1.vdi file to look like this:
00200000 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
00200010 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
*
002001f0 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 55 aa <-- Corrected signature
at 1fe & 1ff
00200200 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
*
002004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00300000
Running with that change alone didn't work. I then used hexedit and placed a CLI opcode (0xFA) as the first byte of the sector. The resulting file now looked like:
v-- CLI instruction
00200000 fa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
00200010 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
*
002001f0 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 55 aa
00200200 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55 aa 55
*
002004c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
00300000
I have placed fa as the first byte int the bootloader. Now when I use your image the error No bootable medium found! System halted no longer appears. This suggests that VirtualBox is looking for more than a boot signature, and is doing some kind of sanity check to determine if the start of the bootloader appears to be executable instructions. This is not uncommon for BIOSes. Some may do such a check, some may not. At this time I haven't looked over the VirtualBox source code to determine the exact checks it performs to make its determination.

Calculating the number of samples in a WAV file

I am currently looking at online examples and here is a WAV file contents in bytes
52 49 46 46 24 08 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00
22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 00 08 00 00 00 00 00 00
24 17 1e f3 3c 13 3c 14 16 f9 18 f9 34 e7 23 a6 3c f2 24 f2 11 ce 1a 0d
and here is the visual; representation:
So according to the Subchunk2Size there is 2048 bytes in the data. The formula to calculate the number of samples in a WAV is given as:
Subchunk2Size /(NumChannels * BitsPerSample/8 ) = NumSamples
If I plugin numbers and according to the information given I get NumSamples = 512. But in the diagram the sample rate is 22050. How can the total number fo samples be less than a single second of samples?
For those wondering, here is a link to the source.
I suspect they are just using a bad example where the duration of the wav file would be less than a second. Their formula makes sense and we can use it to verify the data size of a one second wav file.
If our sample rate is 22050 samples/sec and our wav file is one second, then numSamples = 22050. We know that Subchunk2Size is the number of bytes in the data and can be calculated using this formula: Subchunk2Size = numSamples * numChannels * bitsPerSample / 8 , so, assuming numChannels = 2 and bitsPerSample = 16, we know that a one second wav file should be (22050 * 2 * 16 / 8) bytes which is 88200 bytes, so it would make sense that if Subchunk2Size is 2048 bytes, as per the website's example, then the duration of the wav file would be less than a second and thus, numSamples would be less than 22050.

Converting a sniffed scapy packet to bytes

When sniffing packets with scapy I can save them to a variable
sniffed = sniff(count=1)
Now I would like to see what's inside the packet by doing
print sniffed
or
print str(sniffed)
but all this gives me is something like the following:
������0� E4h##����������� l��
which isn't quite what I need. So how can I convert a sniffed packet into human readable Binary, or an array of Bytes or something more useful so that I can see what's inside? I have already tried using struct.unpack(format, packet) with formats like "!B", but that does not seem to be the right solution, because the packet can be longer than one Byte or a Short or an Int.
Example for what I'm trying
>>> packet = sniff(count=1)[0]
>>> hexdump(packet)
0000 00 50 56 8E 00 0D 14 CC 20 16 E7 59 08 00 45 00 .PV..... ..Y..E.
0010 00 34 6B AB 40 00 40 06 C6 48 AC 11 8A E2 68 10 .4k.#.#..H....h.
0020 69 CC B5 47 00 50 E9 85 17 B0 BA EF 29 B2 80 10 i..G.P......)...
0030 01 DD 8D 58 00 00 01 01 08 0A 00 0E A2 C0 03 5D ...X...........]
0040 9D 1C
>>> packetByteArray = bytearray(repr(str(packet)))
>>> hex(packetByteArray[0])
'0x27'
>>>
But in the hexdump I can see that the first Byte is actually 0x00 and not 0x27
You are probably searching for scapy Hexdump(pkt) or hexraw(pkt) or repr(str(pkt)) for string encoded output. Note that sniff returns a list, not a single pkt.
If you want to access serialized packet bytes one by one just serialize the layers str(pkt) to get a python (char/byte)-string.
for b in str(pkt):
print "char: %s ord/value: %d hex: %x"%(b,ord(b),ord(b))
If you have already read the packet as pkt you may see bytes by time :
pktBytes=[]
pktTimes=[]
from datetime import datetime
#Read each packet and append to the lists.
for p in pkt:
if IP in p:
try:
pktBytes.append(p[IP].len)
pktTime=datetime.fromtimestamp(p.time)
pktTimes.append(pktTime.strftime("%Y-%m-%d %H:%M:%S.%f"))
except:
pass
# Convert list to series
bytes = pd.Series(pktBytes).astype(int)
# Convert the timestamp list to a pd date_time with the option “errors=coerce” to handle errors.
times = pd.to_datetime(pd.Series(pktTimes).astype(str), errors='coerce')
# Build the dataframe, set time as index
df = pd.DataFrame({'Bytes': bytes, 'Times':times})
df = df.set_index('Times')
# See how it looks in 2 seconds sums
df.resample('2S').sum().plot()

ACR1222L FF 82 Load Authentication Keys fails with 63 00 Operation Failed

I'm using ACR1222L NFC smartcard reader with Mifare Plus cards (Security Level 0 as of now; manufacturer default keys A and B). I tried a variety of commands to load authentication key into the reader:
FF 82 00 00 06 FF FF FF FF FF FF
FF 82 00 01 06 FF FF FF FF FF FF
FF 82 20 00 06 FF FF FF FF FF FF
FF 82 00 00 06 A0 A1 A2 A3 A4 A5
FF 82 00 00 06 D3 F7 D3 F7 D3 F7
... and others ...
All of them are returning the error status:
63 00 (Operation Failed)
What could be wrong? I have searched long and wide for a hint, but many other questions are about failed authentication or failed read after successfully loading authentication key with one of the above commands, and they are often based on a different device (ACR122U).
I noticed that the reader does not even respond to the command when a card is not present. Should a card be present on the reader for it to load authentication key?
To be able to use the commands such as "Load Authentication Key", "Authentication (of a block)", Read, Write, Update, etc, the card has to be in Security Level 1 or higher.
There are certain commands to move the card from Security Level 0 to Security Level 1 by loading several relevant keys into the card. Please contact ACS to obtain these commands as they are not publicly documented.
(Additional Info)
Please try command-
0xFF 0x82 0x00 0x60 [key length] [ key value]
or
0xFF 0x82 0x00 0x61 [key length] [ key value]
Where 0x60 to use key Type A and 0x61 for key Type B.

Resources