-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
CodeKevin
committed
Jun 12, 2016
1 parent
c4a94a1
commit 7c27f52
Showing
82 changed files
with
34,337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
CC = gcc | ||
LD = gcc | ||
INCPATHS = -Iopenssl/include -Iwinscard/include | ||
CFLAGS = -W -Wno-write-strings -Wno-unused-function -O4 -DNDEBUG $(INCPATHS) | ||
LIBS = openssl/lib/ssleay32.a openssl/lib/libeay32.a winscard/lib/WinSCard.Lib | ||
|
||
OBJS = iclassified.o | ||
EXES = iclass.exe | ||
|
||
all: $(OBJS) $(EXES) | ||
|
||
%.o : %.c | ||
$(CC) $(CFLAGS) -c -o $@ $< | ||
|
||
%.exe : %.c $(OBJS) | ||
$(LD) $(CFLAGS) $(LDFLAGS) -o $@ $< $(OBJS) $(LIBS) | ||
|
||
clean: | ||
rm -f $(OBJS) $(EXES) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
/* | ||
iClass Key Diversification (iClass Demo) | ||
Copyright (C) 2011 Radboud University Nijmegen | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <openssl/des.h> | ||
#include <windows.h> | ||
#include <winscard.h> | ||
#include "iclassified.h" | ||
#include "stdbyte.h" | ||
|
||
#define PCSC_MAX_DEVICES 16 | ||
byte_t pbtRx[BUF_SIZE]; | ||
size_t szRxLen; | ||
|
||
typedef struct struct_iclass_mem { | ||
byte_t app_limit; | ||
byte_t otp[2]; | ||
byte_t write_lock; | ||
byte_t chip_conf; | ||
byte_t mem_conf; | ||
byte_t eas; | ||
byte_t fuses; | ||
} iclass_mem; | ||
|
||
void print_bytes(const byte_t* bt, size_t len) { | ||
size_t count; | ||
for (count=0; count<len; count++) { | ||
printf("%02x",bt[count]); | ||
} | ||
printf("\n"); | ||
} | ||
|
||
void read_card(SCARDHANDLE hCard){ | ||
int i; | ||
byte_t pbtApduRead[] = { 0x84,0xB0,0x00,0x00,0x00,0x08 }; | ||
for (i = 0; i <= 0x1F; ++i) | ||
{ | ||
if (!SendApdu(hCard,pbtApduRead,sizeof(pbtApduRead),pbtRx,&szRxLen)) { | ||
printf("Error: Could not read block %02x\n", i); | ||
} | ||
print_bytes(pbtRx,szRxLen); | ||
pbtApduRead[3]++; | ||
} | ||
} | ||
|
||
void read_data(SCARDHANDLE hCard, char* block_str){ | ||
int block = strtoul(block_str, NULL, 0); | ||
byte_t read_block[] = { 0x84,0xB0,0x00,block,0x00,0x08 }; | ||
|
||
if (!SendApdu(hCard,read_block,sizeof(read_block),pbtRx,&szRxLen)) { | ||
printf("Error: Could not read block %d\n", block); | ||
return; | ||
} | ||
|
||
print_bytes(pbtRx,szRxLen); | ||
return; | ||
} | ||
|
||
void write_data(SCARDHANDLE hCard, char* block_str, char* data){ | ||
int block = strtoul(block_str, NULL, 0); | ||
|
||
byte_t val[8]; | ||
char* pos = data; | ||
size_t count = 0; | ||
|
||
// Convert hexstring to byte array | ||
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++) { | ||
sscanf(pos, "%2hhx", &val[count]); | ||
pos += 2; | ||
} | ||
|
||
byte_t pbtApduWrite[] = { 0x84,0xD6,0x00,block,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; | ||
|
||
count = 0; | ||
for(count = 0; count < 8; count++){ | ||
pbtApduWrite[5+count] = val[count]; | ||
} | ||
|
||
if (!SendApdu(hCard, pbtApduWrite, sizeof(pbtApduWrite), pbtRx, &szRxLen)) { | ||
printf("Error: Write failed\n"); | ||
print_bytes(pbtRx,szRxLen); | ||
return; | ||
} | ||
|
||
printf("SUCCESS\n"); | ||
return; | ||
} | ||
|
||
void print_help(){ | ||
printf("iclass\n"); | ||
printf("\n"); | ||
printf("Usage:\n"); | ||
printf(" iclass read <block>\n"); | ||
printf(" iclass write <block> <data>\n"); | ||
printf("\n"); | ||
printf("Examples:\n"); | ||
printf(" To read the entire card:\n"); | ||
printf(" iclass read\n"); | ||
printf("\n"); | ||
printf(" To read a specific block:\n"); | ||
printf(" iclass read 6\n"); | ||
printf("\n"); | ||
printf(" To write to a specific block:\n"); | ||
printf(" iclass write 6 4141414141414141\n"); | ||
return; | ||
} | ||
|
||
int main(int argc, char* argv[]) { | ||
|
||
DWORD rc; | ||
DWORD dwActiveProtocol; | ||
SCARDCONTEXT hContext; | ||
SCARDHANDLE hCard; | ||
|
||
size_t szPos = 0; | ||
char acDeviceNames[256 + 64 * PCSC_MAX_DEVICES]; | ||
size_t szDeviceNamesLen = sizeof (acDeviceNames); | ||
DWORD dwDeviceNamesLen; | ||
bool bFoundReader = false; | ||
|
||
bool read = false; | ||
bool write = false; | ||
char* block = NULL; | ||
char* data = NULL; | ||
|
||
// Enough data | ||
if (argc < 2) { | ||
print_help(); | ||
exit(1); | ||
} else if( strcmp(argv[1], "read") != 0 && strcmp(argv[1], "write") != 0){ | ||
print_help(); | ||
exit(1); | ||
} | ||
|
||
// Which command | ||
read = strcmp(argv[1], "read") == 0; | ||
if (!read) { | ||
write = strcmp(argv[1], "write") == 0; | ||
} | ||
|
||
// Which block if there is a block | ||
if (argc > 2){ | ||
block = argv[2]; | ||
|
||
if (write && (argc == 4)){ | ||
data = argv[3]; | ||
if (strlen(data) != 16){ | ||
printf("FAIL: Data written to a block must be 8 bytes\n"); | ||
exit(1); | ||
} | ||
} else if (write && argc <= 4){ | ||
printf("FAIL: Missing data to write\n"); | ||
exit(1); | ||
} | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////// | ||
// Initialize Card Reader | ||
//////////////////////////////////////////////////////////////////// | ||
|
||
rc = SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&hContext); | ||
if(rc != SCARD_S_SUCCESS) { | ||
printf("FAIL: Could not establish smartcard memory context\n"); | ||
return 1; | ||
} | ||
|
||
// Retrieve the string array of all available pcsc readers | ||
dwDeviceNamesLen = (DWORD)szDeviceNamesLen; | ||
if (SCardListReadersA(hContext, NULL, acDeviceNames, &dwDeviceNamesLen) != SCARD_S_SUCCESS) { | ||
printf("FAIL: Could not connect retrieve smartcard reader list\n"); | ||
return false; | ||
} | ||
|
||
while (acDeviceNames[szPos] != '\0') | ||
{ | ||
rc = SCardConnectA(hContext,acDeviceNames+szPos,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); | ||
if(rc != SCARD_S_SUCCESS) { | ||
printf("Failed\n"); | ||
} else { | ||
byte_t pbtApduSecured[] = { 0x84,0x72,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; | ||
if (SendApdu(hCard,pbtApduSecured,sizeof(pbtApduSecured),pbtRx,&szRxLen)){ | ||
bFoundReader = true; | ||
break; | ||
} | ||
printf("Failed\n"); | ||
SCardDisconnect(hCard,SCARD_LEAVE_CARD); | ||
} | ||
// Find next device name position | ||
while (acDeviceNames[szPos++] != '\0'); | ||
} | ||
|
||
if (!bFoundReader) { | ||
printf("FAIL: Could not find OMNIKEY Reader\n"); | ||
return 1; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////// | ||
// INITIALIZE SECURE MODE | ||
//////////////////////////////////////////////////////////////////// | ||
|
||
byte_t pbtApduSecured[] = { 0x84,0x72,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; | ||
if (!SendApdu(hCard, pbtApduSecured, sizeof(pbtApduSecured), pbtRx, &szRxLen)) { | ||
printf("FAIL: Could not start the OMNIKEY secure mode\n"); | ||
return 1; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////// | ||
// AUTHENTICATE | ||
//////////////////////////////////////////////////////////////////// | ||
|
||
byte_t pbtApduAuthKey[] = { 0x84,0x88,0x00,0x21,0x00 }; | ||
if (!SendApdu(hCard,pbtApduAuthKey,sizeof(pbtApduAuthKey),pbtRx,&szRxLen)) { | ||
printf("Error: Authentication failed\n"); | ||
return 1; | ||
} | ||
|
||
//////////////////////////////////////////////////////////////////// | ||
// INITIALIZE SECURE MODE | ||
//////////////////////////////////////////////////////////////////// | ||
|
||
byte_t pbtApduSecured2[] = { 0x84,0x72,0x00,0x01,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; | ||
if (!SendApdu(hCard, pbtApduSecured2, sizeof(pbtApduSecured2), pbtRx, &szRxLen)) { | ||
printf("FAIL: Could not start the OMNIKEY secure mode\n"); | ||
return 1; | ||
} | ||
|
||
|
||
if (read && block){ | ||
read_data(hCard, block); | ||
} else if (read && argc == 2){ | ||
read_card(hCard); | ||
} else if (write){ | ||
write_data(hCard, block, data); | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
try: | ||
import tkinter as tk # Python 3 | ||
from tkinter import messagebox as msgbox | ||
except: | ||
import Tkinter as tk # Python 2 | ||
import tkMessageBox as msgbox | ||
import pygubu | ||
import subprocess | ||
from pprint import pprint | ||
|
||
startupinfo = subprocess.STARTUPINFO() | ||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW | ||
|
||
class Application(pygubu.TkApplication): | ||
def _create_ui(self): | ||
global builder | ||
#1: Create a builder | ||
self.builder = builder = pygubu.Builder() | ||
|
||
#2: Load an ui file | ||
builder.add_from_file('iclass.ui') | ||
|
||
#3: Create the widget using a master as parent | ||
self.mainwindow = builder.get_object('iclass', self.master) | ||
self.set_title('HID iClass Cloner') | ||
|
||
builder.connect_callbacks(self) | ||
|
||
def on_block_select(self, event): | ||
w = event.widget | ||
block = int(w.curselection()[0]) | ||
data = w.get(block) | ||
print block, data | ||
self.load_data(block, data) | ||
|
||
def load_data(self, block, data): | ||
data_entry = self.builder.get_object("Data") | ||
data_entry.delete(0, tk.END) | ||
data_entry.insert(0, data) | ||
|
||
block_entry = self.builder.get_object("Block Choice") | ||
block_entry.delete(0, tk.END) | ||
block_entry.insert(0, block) | ||
|
||
def read_card(self): | ||
print "READCARD" | ||
self.block_list = block_list = self.builder.get_object("Block List") | ||
|
||
self.block_list.bind('<<ListboxSelect>>', self.on_block_select) | ||
self.block_list.delete(0, tk.END) | ||
|
||
self.block_list.bind('<Control-a>', lambda x: self.block_list.select_set(0,tk.END)) | ||
|
||
try: | ||
blocks = subprocess.check_output(['iclass.exe', 'read'], startupinfo=startupinfo).split() | ||
for block in blocks: | ||
block_list.insert(tk.END, block) | ||
except Exception as e: | ||
status = e.output | ||
msgbox.showinfo('Result', status) | ||
|
||
|
||
def write_block(self): | ||
print "WRITEBLOCK" | ||
block_list = self.builder.get_object("Block List") | ||
|
||
block_entry = self.builder.get_object("Block Choice") | ||
block = block_entry.get() | ||
data_entry = self.builder.get_object("Data") | ||
data = data_entry.get() | ||
try: | ||
status = subprocess.check_output(['iclass.exe', 'write' , block, data], startupinfo=startupinfo) | ||
check = subprocess.check_output(['iclass.exe', 'read', block], startupinfo=startupinfo) | ||
print repr(check), repr(data) | ||
if check.strip() != data.strip(): | ||
msgbox.showinfo('Result', "FAIL: Data read does not match data written") | ||
else: | ||
msgbox.showinfo('Result', status) | ||
except Exception as e: | ||
status = e.output | ||
|
||
block_list.delete(block) | ||
block_list.insert(block, data) | ||
|
||
|
||
|
||
if __name__ == '__main__': | ||
root = tk.Tk() | ||
root.resizable(0, 0) | ||
app = Application(root) | ||
app.run() |
Oops, something went wrong.