flipperdevices / flipperzero-good-faps

Flipper Zero Official Apps maintained by Flipper Team and Friends
GNU General Public License v3.0
241 stars 46 forks source link

[NFC Magic] PACK/PWD are not fully written during MF Ultralight, NTAG etc. write on Gen4 #188

Closed mishamyte closed 1 month ago

mishamyte commented 3 months ago

Hello fellow comrades!

Now when NFC Magic writes Gen4 UMC it doesn't write PACK/PWD in all places that are needed, so during the emulation those parameters are not emulated correctly.

Current behavior: The PACK/PWD are written only as a part of the data in the corresponding blocks.

Expected behavior: Those params should be also written in 2 special places of the memory, used by Gen4 chip during the emulation.

Such kind of behavior is well implemented in Proxmark3 hf_mf_ultimatecard.lua script:

-- Write NTAG PWD
local function write_ntagpwd(ntagpwd)
    -- read CONFIG
    if not magicconfig then
    _print = 1
    read_config()
    end
    if ulprotocol == '00' then return nil, 'Magic Card is not using the Ultralight Protocol' end
    -- PWD string checks
    if ntagpwd == nil then return nil, 'empty NTAG PWD string' end
    if #ntagpwd == 0 then return nil, 'empty NTAG PWD string' end
    if #ntagpwd ~= 8 then return nil, 'NTAG PWD wrong length. Should be 4 hex bytes' end
    local info = connect()
    if not info then return false, "Can't select card" end
    print('Writing new NTAG PWD ', ntagpwd)
    local resp = send('A2E5'..ntagpwd) -- must add both for password to be read by the reader command B1
    local resp = send('A2F0'..ntagpwd)
    lib14a.disconnect()
    if resp == nil then
        return nil, 'Failed to write password'
    else
        return true, 'Ok'
    end
end

-- Write PACK
local function write_pack(userpack)
    -- read CONFIG
    if not magicconfig then
    _print = 1
    read_config()
    end
    if ulprotocol == 0 then return nil, 'Magic Card is not using the Ultralight Protocol' end
    -- PACK string checks
    if userpack == nil then return nil, 'empty PACK string' end
    if #userpack == 0 then return nil, 'empty PACK string' end
    if #userpack ~= 4 then return nil, 'PACK wrong length. Should be 4 hex bytes' end
    local info = connect()
    if not info then return false, "Can't select card" end
    print('Writing new PACK', userpack)
    send('A2E6'..userpack..'0000')
    send('A2F1'..userpack..'0000')
    lib14a.disconnect()
    return true, 'Ok'
end

Source

As an example I also attach dump of Gen4 memory with UL11 written and additionally configured for the correct emulation. It has comments for described fields: gen4-mfu.json

Also in the Proxmark3 Magic Card Notes there is next highlight:

Don't forget configure maximum read/write blocks. It's can be adjusted directly in config (see Dump configuration) or by command 6B:

So far I see we don't configure that number in code and write signature blocks outside of allowed blocks:

if(instance->current_block == 0) {
            instance->total_blocks = 64;
            instance->config[0] = 0x01;
            switch(mfu_data->type) {
            case MfUltralightTypeNTAG203:
            case MfUltralightTypeNTAG213:
            case MfUltralightTypeNTAG215:
            case MfUltralightTypeNTAG216:
            case MfUltralightTypeNTAGI2C1K:
            case MfUltralightTypeNTAGI2C2K:
            case MfUltralightTypeNTAGI2CPlus1K:
            case MfUltralightTypeNTAGI2CPlus2K:
                instance->config[27] = Gen4PollerUltralightModeNTAG;
                instance->total_blocks = 64 * 2;
                break;

            case MfUltralightTypeUL11:
            case MfUltralightTypeUL21:
                // UL-C?
                // UL?
            default:
                instance->config[27] = Gen4PollerUltralightModeUL_EV1;
                break;
            }

For now it looks like it works fine, but it also could be the point of a mistake, so I decided to highlight it there.

Thank you a lot and pls feel free to contact me for the additional info and/or testing of that functionality.

Astrrra commented 1 month ago

Solved in #190, please reopen the issue if it is still present