RfidResearchGroup / proxmark3

Iceman Fork - Proxmark3
http://www.icedev.se
GNU General Public License v3.0
3.72k stars 998 forks source link

segfault when reading using wire #2184

Closed l0rdg3x closed 8 months ago

l0rdg3x commented 8 months ago

Describe the bug segfault when reading using wire

To Reproduce Steps to reproduce the behavior: [usb] pm3 --> emv reader -w [=] PPSE get SFI: 0x01. [=] Get SFI: 0x01. num: 0x01 [=] Get SFI: 0x01. num: 0x02 [=] Get SFI: 0x01. num: 0x03 [=] Get SFI: 0x01. num: 0x04 [=] * PPSE get SFI. End of records. [=] Application.......... xxxxxxx [=] Label................ xxxxxx [=] Language............. xxxxx [=] Effective date....... xxxxxxx [=] Expiration date...... xxxxxxx [=] PAN.................. xxxxxxxxx [=] PAN Sequence......... 1 [1] 129973 segmentation fault sudo proxmark3 /dev/ttyACM0

dmesg: [36851.911768] WorkerThread[129980]: segfault at 7feae8dfe66c ip 00005558e8a418c8 sp 00007fe9e8dfe310 error 4 in proxmark3[5558e88d2000+23e000] likely on CPU 4 (core 4, socket 0) [36851.911804] Code: 85 c5 00 00 00 85 db 0f 84 e9 00 00 00 83 fb 01 0f 84 9c 00 00 00 49 8b 06 48 83 f8 01 0f 86 c3 01 00 00 48 8d 50 fe 49 89 16 <41> 0f b6 5c 04 fe 41 0f b6 44 04 ff c1 e3 08 01 c3 4d 85 ed 74 05

Desktop (please complete the following information): Manjaro Linux Unstable [ Proxmark3 RFID instrument ]

MCU....... AT91SAM7S512 Rev A
Memory.... 512 KB ( 68% used )

Client.... Iceman/master/v4.17511-21-g43f64887f 2023-11-23 13:42:17
Bootrom... Iceman/master/v4.17511-21-g43f64887f-suspect 2023-11-23 13:42:38 
OS........ Iceman/master/v4.17511-21-g43f64887f-suspect 2023-11-23 13:42:53 
Target.... RDV4
wh201906 commented 8 months ago

Maybe you could add the debug flag when building and run the client in gdb, then you can find where it crashes https://github.com/RfidResearchGroup/proxmark3/commit/ffb6f4ddbbd972c8a21accb26cf7e47195eb41d2

iceman1001 commented 8 months ago

some where near [=] PAN Sequence......... 1 message...

could be a wrong size decoding.

l0rdg3x commented 8 months ago

I'm sorry, I don't know how to use gdb. Any advice?

l0rdg3x commented 8 months ago

miss click

wh201906 commented 8 months ago

Well you'd better search for some tutorials to guide you with more details. Basically you need to do the following things:

  1. Build the client with debug info. You need to revert the changes in commit ffb6f4ddbbd972c8a21accb26cf7e47195eb41d2 then build the client
  2. Load the client with gdb. You should run gdb --args proxmark3 -p <port>. the proxmark3 there should be replaced with the executable path on your PC.
  3. Run the client and reproduce the crash
  4. Run backtrace to get where it crashes.

I only have little experience about gdb so these steps might not be the optimal, but they do work more or less.

l0rdg3x commented 8 months ago
[usb] pm3 --> emv reader -w
[=] * PPSE get SFI: 0x01.
[=] * * Get SFI: 0x01. num: 0x01
[=] * * Get SFI: 0x01. num: 0x02
[=] * * Get SFI: 0x01. num: 0x03
[=] * * Get SFI: 0x01. num: 0x04
[=] * * PPSE get SFI. End of records.
[=] Application.......... xxxxxxx
[=] Label................ xxxxxxxxxxx
[=] Language............. xxxxxxxxxx
[=] Effective date....... xxxxxxxxxx
[=] Expiration date...... xxxxxxxx
[=] PAN.................. xxxxxxxxxxx
[=] PAN Sequence......... 1

Thread 5 "WorkerThread" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe09ff6c0 (LWP 31894)]
Iso7816ExchangeEx (channel=channel@entry=CC_CONTACT, activate_field=activate_field@entry=false, leave_field_on=leave_field_on@entry=true, apdu=..., include_le=include_le@entry=true, le=<optimized out>, le@entry=0, 
    result=result@entry=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", max_result_len=260, result_len=0x7fffe09fe5c8, sw=0x7fffe09fe5b6) at src/iso7816/iso7816core.c:171
171         uint16_t isw = (result[*result_len] * 0x0100) + result[*result_len + 1];
(gdb) backtrace
#0  Iso7816ExchangeEx (channel=channel@entry=CC_CONTACT, activate_field=activate_field@entry=false, leave_field_on=leave_field_on@entry=true, apdu=..., include_le=include_le@entry=true, le=<optimized out>, 
    le@entry=0, result=result@entry=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", max_result_len=260, result_len=0x7fffe09fe5c8, sw=0x7fffe09fe5b6) at src/iso7816/iso7816core.c:171
#1  0x0000555555729c37 in EMVExchangeEx
    (ActivateField=false, IncludeLe=true, tlv=0x7fffdc061bb0, sw=0x7fffe09fe5b6, ResultLen=0x7fffe09fe5c8, MaxResultLen=260, Result=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", apdu=..., LeaveFieldON=<optimized out>, channel=CC_CONTACT) at src/emv/emvcore.c:278
#2  EMVReadRecord
    (channel=channel@entry=CC_CONTACT, LeaveFieldON=LeaveFieldON@entry=true, SFI=SFI@entry=2 '\002', SFIrec=SFIrec@entry=2 '\002', Result=Result@entry=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", MaxResultLen=MaxResultLen@entry=260, ResultLen=0x7fffe09fe5c8, sw=0x7fffe09fe5b6, tlv=0x7fffdc061bb0) at src/emv/emvcore.c:581
#3  0x000055555571cccb in CmdEMVReader (Cmd=<optimized out>) at src/emv/cmdemv.c:2853
#4  0x0000555555705e2e in CmdsParse (Commands=0x5555559b8a20 <CommandTable>, Cmd=0x7fffdc05fcf4 "reader -w") at src/cmdparser.c:321
#5  0x0000555555705e2e in CmdsParse (Commands=Commands@entry=0x5555559b7b60 <CommandTable>, Cmd=Cmd@entry=0x7fffdc05fcf0 "emv reader -w") at src/cmdparser.c:321
#6  0x000055555570447f in CommandReceived (Cmd=Cmd@entry=0x7fffdc05fcf0 "emv reader -w") at src/cmdmain.c:365
#7  0x000055555577b964 in main_loop (script_cmds_file=<optimized out>, script_cmd=<optimized out>, stayInCommandLoop=true) at src/proxmark3.c:428
#8  0x00007ffff62f371a in  () at /usr/lib/libQt5Core.so.5
#9  0x00007ffff5caa9eb in  () at /usr/lib/libc.so.6
#10 0x00007ffff5d2e7cc in  () at /usr/lib/libc.so.6
wh201906 commented 8 months ago

Could you please wrap the output with ``` ? It will look much better ``` output1 output2 ``` ->

output1
output2
wh201906 commented 8 months ago

Could you please add this line

PrintAndLogEx(INFO, "result_len: %zu", *result_len);

before Line 171 of proxmark3/client/src/iso7816/iso7816core.c and compile the client and test again? I need to check if the value of result_len is correct.

After this change, the code around there should look like this:

    if (*result_len < 2) {
        return 200;
    }

    *result_len -= 2;
    PrintAndLogEx(INFO, "result_len: %zu", *result_len); // new line there
    uint16_t isw = (result[*result_len] * 0x0100) + result[*result_len + 1];

    if (sw) {
        *sw = isw;
    }
l0rdg3x commented 8 months ago
[usb] pm3 --> emv reader -w
[=] result_len: 49
[=] result_len: 38
[=] * PPSE get SFI: 0x01.
[=] * * Get SFI: 0x01. num: 0x01
[=] result_len: 41
[=] * * Get SFI: 0x01. num: 0x02
[=] result_len: 37
[=] * * Get SFI: 0x01. num: 0x03
[=] result_len: 30
[=] * * Get SFI: 0x01. num: 0x04
[=] result_len: 0
[=] * * PPSE get SFI. End of records.
[=] result_len: 64
[=] result_len: 60
[=] result_len: 49
[=] result_len: 60
[=] Application.......... xxxx
[=] Label................ xxxxx
[=] Language............. xxxx
[=] result_len: 0
[=] result_len: 0
[=] result_len: 4
[=] result_len: 0
[=] result_len: 20
[=] result_len: 12
[=] result_len: 138
[=] Effective date....... xxxxxxx
[=] Expiration date...... xxxxxx
[=] PAN.................. xxxxxxxxxxxxxxxx
[=] PAN Sequence......... 1
[=] result_len: 4294967292

Thread 5 "WorkerThread" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffe09ff6c0 (LWP 39604)]
0x000055555574bc8b in Iso7816ExchangeEx (channel=channel@entry=CC_CONTACT, activate_field=activate_field@entry=false, leave_field_on=leave_field_on@entry=true, apdu=..., include_le=include_le@entry=true, le=<optimized out>, le@entry=0, 
    result=result@entry=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", max_result_len=260, result_len=0x7fffe09fe5c8, sw=0x7fffe09fe5b6) at src/iso7816/iso7816core.c:172
172         uint16_t isw = (result[*result_len] * 0x0100) + result[*result_len + 1];
(gdb) backtrace
#0  0x000055555574bc8b in Iso7816ExchangeEx (channel=channel@entry=CC_CONTACT, activate_field=activate_field@entry=false, leave_field_on=leave_field_on@entry=true, apdu=..., include_le=include_le@entry=true, le=<optimized out>, 
    le@entry=0, result=result@entry=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", max_result_len=260, result_len=0x7fffe09fe5c8, sw=0x7fffe09fe5b6) at src/iso7816/iso7816core.c:172
#1  0x0000555555729c37 in EMVExchangeEx
    (ActivateField=false, IncludeLe=true, tlv=0x7fffdc061bb0, sw=0x7fffe09fe5b6, ResultLen=0x7fffe09fe5c8, MaxResultLen=260, Result=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", apdu=..., LeaveFieldON=<optimized out>, channel=CC_CONTACT) at src/emv/emvcore.c:278
#2  EMVReadRecord
    (channel=channel@entry=CC_CONTACT, LeaveFieldON=LeaveFieldON@entry=true, SFI=SFI@entry=2 '\002', SFIrec=SFIrec@entry=2 '\002', Result=Result@entry=0x7fffe09fe690 "l\344\207_%\003\025\021!_$\003!\0040\237\a\002\377\300Z\bS3\027\020$XUR_4\001\001\216\024", MaxResultLen=MaxResultLen@entry=260, ResultLen=0x7fffe09fe5c8, sw=0x7fffe09fe5b6, tlv=0x7fffdc061bb0) at src/emv/emvcore.c:581
#3  0x000055555571cccb in CmdEMVReader (Cmd=<optimized out>) at src/emv/cmdemv.c:2853
#4  0x0000555555705e2e in CmdsParse (Commands=0x5555559b8a20 <CommandTable>, Cmd=0x7fffdc05fcf4 "reader -w") at src/cmdparser.c:321
#5  0x0000555555705e2e in CmdsParse (Commands=Commands@entry=0x5555559b7b60 <CommandTable>, Cmd=Cmd@entry=0x7fffdc05fcf0 "emv reader -w") at src/cmdparser.c:321
#6  0x000055555570447f in CommandReceived (Cmd=Cmd@entry=0x7fffdc05fcf0 "emv reader -w") at src/cmdmain.c:365
#7  0x000055555577b964 in main_loop (script_cmds_file=<optimized out>, script_cmd=<optimized out>, stayInCommandLoop=true) at src/proxmark3.c:428
#8  0x00007ffff62f371a in  () at /usr/lib/libQt5Core.so.5
#9  0x00007ffff5caa9eb in  () at /usr/lib/libc.so.6
#10 0x00007ffff5d2e7cc in  () at /usr/lib/libc.so.6
wh201906 commented 8 months ago

So the result_len is set to (the max of uint32_t) - 3, which causes this bug.

wh201906 commented 8 months ago

I managed to get the similar error on my Proxmark3 Easy. I'll debug it locally. Thanks for your help @l0rdg3x

l0rdg3x commented 8 months ago

Thanks to you @wh201906, glad to help as i can.

wh201906 commented 8 months ago

I think it's caused by

            if (len == 0) {
                if (verbose) PrintAndLogEx(WARNING, "smart card response failed");
                return -2;
            }

in smart_wait() of /client/src/cmdsmartcard.c

wh201906 commented 8 months ago

I've fixed it in #2186

l0rdg3x commented 8 months ago

Awesome! Thanks @wh201906 I'm ready to git pull and recompile