#!/bin/sh # getChallengeResponse.sh - login to my online banking website using the challenge-reponse mechanism # Purpose of this script (work in progress) is to further automate online banking. # More info: http://globalblindspot.blogspot.be/2010/07/getting-emvcap-challengeresponse-to.html # Author: Tom Van Braeckelpin="$1" challenge="$2" if [ -z "$pin" -o `expr length "$pin"` -ne 4 -o -z "$challenge" -o `expr length "$challenge"` -ne 8 ]; then echo "Usage: $0 " echo "Example: $0 3117 12345678" exit 1 fi # Can you guess what this method does ? bintodec() { bin="$1" echo "obase=10; ibase=2; $bin" | bc } # remove < and " " compact() { while read line; do echo "$line" | tr -d '<' | tr -d ' ' done } # args: command to execute on the card execOnCard() { cla="$1" ins="$2" p1="$3" p2="$4" le="$5" data="$6" tosend="${cla}${ins}${p1}${p2}${le}${data}" #echo "Sending $tosend" >&2 echo "$tosend" | scriptor 2>/dev/null | grep -A 10000 "<" # does not work: # echo "$cla $ins $p1 $p2 $le $data" | scriptor 2>/dev/null | grep "<" } execOnCardRespond() { cla="$1" ins="$2" p1="$3" p2="$4" le="$5" data="$6" result=$(execOnCard $cla $ins $p1 $p2 $le $data) ; echo "result = $result" >&2 # get length in hex length=$(echo "$result" | cut -d ' ' -f 3); #echo "length = $length" execOnCard 00 c0 00 00 $length | compact } # Can you guess what this method does ? hextobin() { hex="$1" echo "ibase=16; obase=2; $hex" | bc } # do a read data with the correct length... readData() { p2="$1" recordLength=$(execOnCard 80 ca 9f $p2 00 | cut -d ' ' -f 3) #echo "recordLength = $recordLength" >&2 # cut off first bytes (status code, length) # cut off last bytes (9000Normalprocessing) # for some reason we NEED CLA 80 here, 00 doesn't work... execOnCard 80 ca 9f $p2 $recordLength | compact | tail -c +7 | head -c -23 echo } readRecord() { p1="$1" p2="$2" errorWithLength=$(execOnCard 00 b2 $p1 $p2 00) #echo "errorWithLength = $errorWithLength" recordLength=$(echo "$errorWithLength" | cut -d ' ' -f 3) #echo "recordLength = $recordLength" execOnCard 00 b2 $p1 $p2 $recordLength | compact } readRecords() { SFI="$1" # five most significant bits recNr="$2" # second byte lastRecNr="$3" # third byte if [ "$SFI" = "1" ]; then p2=0c # (sfi << 3) + 4 else echo "I don't know p2 !" sleep 3 fi # READ RECORD(s) for i in `seq $recNr $lastRecNr`; do readRecord 0$i $p2 done } zeropadfront() { targetLength="$1" # echo "targetLength = $targetLength" while read line; do # echo "got line $line" length=$(expr length "$line") while [ $length -lt $targetLength ]; do line="0${line}" length=$(expr length "$line") done echo "$line" done } ################################################################# ###################### EXECUTION STARTS HERE #################### ################################################################# # reset execOnCard reset #select file/application aid=A0000000048002 # securecode aut #aid=A0000000043060 # maestro (debit) response=$(execOnCardRespond 00 a4 04 00 07 ${aid}) echo $response # this is needed, otherwise the commands below fail... PDOL=$(echo "$response" | grep -o -E "9F38........" | tail -c +7) echo "PDOL = $PDOL" # for securecode get a PDOL of "9F3501" (eg "9F38039F3501") # this is the "Terminal Type" - don't know the value, but I use 00... # get processing options: # - Application Interchange Profile (AIP) # - Application File Locator (AFL) if [ -z "$PDOL" ]; then response=$(execOnCardRespond 80 a8 00 00 02 8300); echo $response # eg: ...94080801030110010201 AIP=3800 # this means "initiate", "data auth", RFU AFLs="08010301 10010201" else # PDOL specifies one tag with value of 1 byte, but I don't know which value... response=$(execOnCardRespond 80 a8 00 00 03 830100); echo $response # 770E82021000940808010100080404009000:Normalprocessing. AIP=1000 # this means "initiate" AFLs="08010100 08040400" fi echo "Found AIP = $AIP and AFLs = $AFLs" # Read SecureCode records and extract valueable info cardinfo=$(readRecords 1 1 1) PAN=$(expr substr "$cardinfo" 9 18) echo "Application Primary Account Number (PAN) = $PAN" authinfo=$(readRecords 1 4 4) bitmap=$(expr substr "$authinfo" 11 22) echo "Proprietary Authentication Challenge-Reponse Bitmap = $bitmap" # This works for maestro: if false; then readRecords 1 1 3 # second group in AFL SFI=10 # five most significant bits recNr=1 # second byte lastRecNr=2 # third byte offlineDataRec=1 # fourth byte # p2=binary(firstbyte)100 left shift 3 OR 100 ??? # p2=binary(firstbyte) shift right 3 # I calculated 84, but it seems to be (13) 14 / (1B) 1C / (23) 24 # and also 03 04 0B 0C but we found those above p2s="14 1C 24" # READ RECORD(s) for p2 in $p2s; do for i in `seq $recNr $lastRecNr`; do echo -n "p2 = $p2, recordNr = $i: " readRecord 0$i $p2 done done fi # get pin try counter length pinTry=$(readData 17) echo "pinTry = $pinTry" if [ "$pinTry" != "02" -a "$pinTry" != "03" ]; then echo "WARNING: pinTry < 2 !" sleep 15 fi # get Application Transaction Counter echo -n "Application Transaction Counter = " readData 36 # get Last Online ATC Register echo -n "Last Online ATC Register = " readData 13 echo -n "Log Entry = " readData 4D echo -n "Log Format = " readData 4F # submit pin execOnCard 00 20 00 80 08 24${pin}FFFFFFFFFF # generate Application RQ Cryptogram # p1=80=Authorisation Request Cryptogram countrycode=0056 # OTF mentions 0000, chip&pin uses 0826 currencycode=0978 # OTF mentions 0000, chip&pin uses 0826 date=$(date +"%y%m%d") CardholderVerificationMethodResults=010002 # 8000000000 = Terminal Verification Codes: Data authentication was not performed (recommended by optimized to fail) # 00 = transaction type # 0000 = ICC Dynamic Number ARQC_response=$(execOnCardRespond 80 AE 80 00 22 000000000000000000000000${countrycode}8000000000${currencycode}${date}00${challenge}0000${CardholderVerificationMethodResults}) echo "ARQC_response = $ARQC_response" CID=$(expr substr "$ARQC_response" 11 2) ATC=$(expr substr "$ARQC_response" 19 4) AC=$(expr substr "$ARQC_response" 29 16) #IAD=$(expr substr "$ARQC_response" 51 15) # testing to see if we get the same response as in chip&pin - we do, so this is OK. # CID=80; ATC=A52D; AC=AD452EF6BA769E4A; IAD=06770A03A48000; bitmap=00001F00000000000FFFFF00000000008000 # generate Application Cryptogram for challenge 12345678 # 5a33 = Authorisation Response Code, generated by terminal or bank (for online stuff) IAuthData=0000000000000000000000000000000000000000 # Issuer Authentication Data (NOT Issuer Application Data !) AC_response=$(execOnCardRespond 80 AE 00 00 2e 5a33000000000000000000000000${countrycode}8000000000${currencycode}${date}00${challenge}0000${CardholderVerificationMethodResults}${IAuthData}) echo "AC_response = $AC_response" #AC_response="$ARQC_response" # Testing which response we need - normally the second one, but let's try this for a laugh CID=$(expr substr "$AC_response" 11 2) ATC=$(expr substr "$AC_response" 19 4) AC=$(expr substr "$AC_response" 29 16) # extract response echo "CID=$CID, ATC=$ATC, AC=$AC, IAD=$IAD" # length of bitmap is used as the target length for the response bitmap_hex_length=$(expr length "$bitmap") bitmap_bin_length=$(expr "$bitmap_hex_length" \* 4) echo bitmap_hex_length=$bitmap_hex_length, bitmap_bin_length=$bitmap_bin_length # Do logical AND with bitmap CIDATCAC_bin=$(hextobin "${CID}${ATC}${AC}${IAD}" | zeropadfront "$bitmap_bin_length") echo "CIDATCAC_bin = $CIDATCAC_bin" bitmap_bin=$(hextobin "$bitmap" | zeropadfront "$bitmap_bin_length") echo " bitmap_bin = $bitmap_bin" # if a bit of bitmap = 1, then we add the bit from CIDATCAC_bin to filtered_bin filtered_bin= for bitpos in `seq 1 $bitmap_bin_length`; do bitmap_bit=$(expr substr "$bitmap_bin" "$bitpos" 1) if [ $bitmap_bit -eq 1 ]; then CIDATCAC_bin_bit=$(expr substr "$CIDATCAC_bin" "$bitpos" 1) filtered_bin=${filtered_bin}${CIDATCAC_bin_bit} fi done echo "filtered_bin = $filtered_bin" # Note: if ATC>0x26(38) then response = 8 characters # if ATC=0xFFFF(65536) then response = 12 characters !!! is this correct ? filtered_dec=$(bintodec $filtered_bin) echo "RESPONSE = $filtered_dec" exit # this is never executed if false; then # Make AND of ARQC and Cap bit Filter: fortis: 77269F2701 00 9F3602 00B7 9F260886F857BEB767E8FB 9F100F 0601560384B0A80701030000000000 kbc: 77269F2701 00 9F3602 0004 9F260831F94BDAB5DF0F38 9F100F 0601560384B0400701030000000000 kbc: 77269F2701 00 9F3602 0005 9F2608B29D6D20BFE004AD 9F100F 0601560384B0400701030000000000 # extracted values output 00 00B7 86F857BEB767E8FB 0601560384B0A80701030000000000 output 00 0004 31F94BDAB5DF0F38 0601560384B0A80701030000000000 bitmask 00 00FF 000000000003FFFF filter .. ..04 ...........30F38 binary 0100 110000111100111000 decimal 1249080 fi Example protocol log: Collected from a NatWest reader and card performing a respond computation (ISO 7816, T=0 protocol). Personal details have been redacted. Command: 00a4040007 (select application) Proc: a4 Data: a0000000048002 Proc: 61 Status: 6112 (more data available) Command: 00c0000012 (application selected) Proc: c0 Data: 6f108407a0000000048002a5055f2d02656e Proc: 90 Status: 9000 (OK) Command: 80a8000002 (initiate transaction) Proc: a8 Data: 8300 Proc: 61 Status: 6108 (more data available) Command: 00c0000008 (transaction initiated) Proc: c0 Data: 8006100008010100 Proc: 90 Status: 9000 (OK) Command: 00b2010c00 (get static data length) Proc: 6c Status: 6c57 (wrong length) Command: 00b2010c57 (read static data) Proc: b2 Data: 7055 8e0a 00000000000000000100 (CVM list) 9f5501 a0 (unknown) 9f5612 00001f00000000000fffff00000000008000 (bit filter) 8c15 9f02069f03069f1a0295055f2a029a039c019f3704 (CDOL1) 8d17 8a029f02069f03069f1a0295055f2a029a039c019f3704 (CDOL2) Proc: 90 Status: 9000 (OK) Command: 80ca9f1700 (get PIN try counter length) Proc: 6c Status: 6c04 (wrong length) Command: 80ca9f1704 (get PIN try counter) Proc: ca Data: 9f170103 (3 remaining tries) Proc: 90 Status: 9000 (OK) PIN entered: ? Command: 0020008008 (verify PIN) Proc: 20 Data: 24xxxxffffffffff Proc: 90 Status: 9000 (OK) Challenge entered: 12345678 Command: 80ae80001d (generate ARQC) Proc: ae Data: 0000000000000000000000000000800000000000000000000012345678 Proc: 61 Status: 6114 (more data available) Command: 00c0000014 (return ARQC) Proc: c0 Data: 80 1280 0042b7f9a572da74caff 06770a03a48000 Proc: 90 Status: 9000 (OK) Command: 80ae00001f (generate AC) Proc: ae Data: 5a330000000000000000000000000000800000000000000000000012345678 Proc: 61 Status: 6114 (more data available) Command: 00c0000014 (return AAC) Proc: c0 Data: 80 1200 00424f1c597723c97d78 06770a03258000 Proc: 90 Status: 9000 (OK) Response returned: 4822527
Various wacky and hacky technological research projects, shared with the world so that restless brains may find peace of mind here.
vrijdag 31 mei 2013
getChallengeResponse.sh script
donderdag 31 januari 2013
Love is Math As Well
We don't remember what it was like
that first time
what we talked about
whether we showed each other things
which we didn't yet have
the stale wines
in the polished vases
warm bodies in winter
whether we read
from closed books
added ourselves together and
knew we never
would have to divide
together exponential
a multiplication with
in the cross that we
no longer wanted to carry
a conclusive casting out of nines.
[I translated "Liefde is ook Wiskunde" by Bart Plouvier from Dutch to English for the national poetry day in Belgium.]
Abonneren op:
Posts (Atom)