#!/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
Abonneren op:
Reacties posten (Atom)
Geen opmerkingen:
Een reactie posten