• XSS.stack #1 – первый литературный журнал от юзеров форума

MSR605X

nightly

root@usss-int:~#
Premium
Регистрация
03.10.2019
Сообщения
375
Реакции
413
pip3 install pyusb

Python:
from typing import Generator, Iterable, Tuple
from time import sleep, time
from sys import argv

from usb.core import find as find_device, USBTimeoutError


class Reader:
    def __init__(self) -> None:
        self.esc = b"\x1b"

        print('[?] Looking for device')

        self.device = find_device(
            find_all=False, idVendor=0x0801, idProduct=0x0003
        )

        if self.device is None:
            print('[-] Device is not found')
            exit(0)

        print('[+] Device is online')

        if self.device.is_kernel_driver_active(0):
            print('[+] Disabling drivers')
            self.device.detach_kernel_driver(0)
            print('[+] Driver disabled')

        try:
            print('[+] Setting up configuration')
            self.device.set_configuration()
            print('[+] Resetting driver')
            self.device.reset()
        except Exception as e:
            print('[-] Error while setting up:', e)
            exit(0)

        print('[+] All setups done')

    def _make_header(self, ssequ: bool, eof_sequ: bool, length: int) -> bytes:
        if length < 0 or length > 63:
            raise ValueError("Len must be a non-negative number no mo than 63")

        header = length

        if ssequ:
            header |= 0b10000000
        if eof_sequ:
            header |= 0b01000000

        return bytes([header])

    def _encapsulate_message(
        self, message: bytes
    ) -> Generator[bytes, bytes, None]:
        idx = 0

        while idx < len(message):
            payload = message[idx:idx+63]
            header = self._make_header(
                idx == 0, len(message) - idx < 64, len(payload)
            )
            padding = b"\0" * (63 - len(payload))
            yield header + payload + padding
            idx += 63

    def _send_packet(self, packet: bytes) -> None:
        self.device.ctrl_transfer(
            0x21, 9, wValue=0x0300, wIndex=0, data_or_wLength=packet
        )

    def _recv_packet(self, buff: int, timeout: int) -> bytes:
        try:
            return bytes(self.device.read(0x81, buff, timeout))
        except USBTimeoutError:
            self.device.reset()
            return b'timeout'
        except Exception as e:
            print('Error:', e)
            self.device.reset()
            return b''

    def recv_message(
        self, buff: int = 1024, timeout: int = 500, nocheck: bool = False
    ) -> bytes:
        message = b''
        retries = 0

        while True:
            if retries == 14:
                print('[!] Operation timeout')
                return message

            packet = self._recv_packet(buff, timeout)

            if packet == b'timeout':
                retries += 1
                continue

            if not packet and not message:
                return b''
            elif nocheck:
                return packet

            payload_length = packet[0] & 0b00111111
            payload = packet[1:1+payload_length]
            message = message + payload

            if packet[0] & 0b01000000:
                break

        return message

    def send_message(self, message: bytes, reset: bool = True) -> None:
        if reset:
            self.device.reset()

        for packet in self._encapsulate_message(message):
            self._send_packet(packet)

    def read_tracks(self) -> Tuple[bytes, bytes, bytes]:
        print('[!] Please swipe card')
        self.send_message(self.esc + b"r")
        ret = self.recv_message(nocheck=True)

        if not ret:
            return (b'', b'', b'')

        print('[+] Extraction T1&T2')

        with open('FILE', 'wb') as file:
            print('Saved in temp:', ret)
            file.write(ret)

        with open('FILE', 'rb') as file:
            print('Readed fftemp:', file.read())

        track1 = ret[
            ret.index(b'\x1b\x01')+3:ret.index(b'\x1b\x02')
        ].replace(b'\x3f', b'')
        track2 = ret[
            ret.index(b'\x1b\x02')+2:ret.index(b'\x1b\x03')
        ].replace(b'\x3f', b'')
        track3 = ret[ret.index(b'\x1b\x03'):].replace(b'\x3f', b'')

        self.device.reset()

        return (track1, track2, track3)

    def write(self, tracks: Tuple[bytes, bytes, bytes]) -> bool:
        if len(tracks) != 2 and len(tracks) != 3:
            print('[-] Write error. You must have 2-3 tracks to write')
            return False

        self.send_message(self.esc+b'w')

        data = self.esc+b's'  # Section 9; <ESC>w<ESC>s[DATA]

        for i in range(1, len(tracks)+1, 1):
            data += self.esc+i.to_bytes(1, 'little')+tracks[i-1]
            # <ESC><Track NO><STR>

        data += b'\x3f\x1c'  # Ending Field:   ?<FS>

        print('[+] Swipe card for write')
        self.send_message(data, False)
        sleep(2)
        answ = self.recv_message(nocheck=True)

        print('Data:', data)
        print('Answer:', answ)
        return True

    def get_firmware_version(self) -> bytes:
        self.send_message(self.esc + b"v")
        ret = self.recv_message()
        assert ret[0:1] == self.esc
        return ret[1:]

    def set_hi_co(self) -> bytes:
        self.send_message(self.esc + b"x")
        ret = self.recv_message()
        assert ret[0:1] == self.esc
        return ret[1:]

    def set_low_co(self) -> bytes:
        self.send_message(self.esc + b"y")
        ret = self.recv_message()
        assert ret[0:1] == self.esc
        return ret[1:]

    def get_hi_low_co_status(self) -> None:
        self.send_message(self.esc + b"d")
        ret = self.recv_message()
        assert ret[0:1] == self.esc

        print(f'Current status: {"Low" if ret[1:] == b"l" else "Hi"}-Co')

    def get_device_model(self) -> bytes:
        self.send_message(self.esc + b"t")
        ret = self.recv_message()
        assert ret[0:1] == self.esc
        return ret[1:]

    def save_to_file(self, tracks: Iterable[bytes]) -> None:
        with open(f'{int(time()*1000)}.tracks', 'wb') as tfile:
            tfile.write(b'\n'.join(tracks))

    def write_from_file(self, filename: str = 'FILE') -> bool:
        tracks = []

        with open(filename, 'rb') as file:
            for line in file:
                print('Track:', line)
                tracks.append(line.strip())

        self.write((tracks[0], tracks[1], tracks[2]))

        return True

    def compare(self) -> None:
        print('[!] Reading first card data...')
        c1t1, c1t2, c1t3 = self.read_tracks()
        print('[+] First card readed go to second card...')
        c2t1, c2t2, c2t3 = self.read_tracks()

        assert c1t1 == c2t1, "First track not match"
        assert c1t2 == c2t2, "Second track not match"
        assert c1t3 == c2t3, "Third track not match"

        print('[+] Passed. Both cards have same data.')

    def earse(self, tracks: Tuple[bool, bool, bool]) -> bool:
        code = 0

        if all(tracks):
            code = 7

        if tracks[1]:
            code += 2
        if tracks[2]:
            code += 4

        data = self.esc+b'c'+bin(code)
        print(data)

        return False

        print('[!] Swipe card for earse')

        self.send_message(data)
        ret = self.recv_message()

        print(ret)
        return True


if __name__ == '__main__':
    valid_cmd = ('r', 'rs', 'w', 'c', 'e')

    if len(argv) < 2:
        print('[!] No command exiting')
        exit(0)
    elif argv[1] not in valid_cmd:
        print(f'[?] Unknown command: {argv[1]}; Valid: {valid_cmd}')
        exit(0)

    msrx = Reader()
    msrx.set_hi_co()

    if argv[1] == 'c':
        msrx.compare()
    elif argv[1] == 'e':
        msrx.earse((True, True, True))
    elif argv[1] == 'r' or argv[1] == 'rs':
        tracks = msrx.read_tracks()
        print('Tracks:', tracks)

        if argv[1] == 'rs':
            msrx.save_to_file(tracks)
    elif argv[1] == 'w':
        if len(argv) != 3:
            print('[!] main.py w FILENAME')
            exit(0)
        msrx.write_from_file(argv[2])
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх