# Writeup for Bank CRYPTO (90) 
> Description: Everyone knows that banks are insecure. This one super secure and only allows only 20 transactions per session. I always wanted a million on my account.
![crypto90.zip](crypto90.zip)
I started analysing behaviour of the given script
    b@x:~/Desktop/task > python bank.py     WELCOME TO THE BANK BACKEND!       Possible commands:  	    help - Prints this message  	    create  - Creates a new transaction with amount  	    complete <tid> <hash> - Completes a transaction to the current account. <tid> is the transaction ID to use and <hash> the verification hash.       Your balance: 0, 20 transactions left.      Command: create 1000      Transaction #0 over 1000 initiated. Please complete it using the verification code: 527f692949701f5f273a1e552248342366      Your balance: 0, 19 transactions left.      Command: complete 0 527f692949701f5f273a1e552248342366      Transaction completed!      Your balance: 1000, 19 transactions left.      Command: create 5000      Transaction #1 over 5000 initiated. Please complete it using the verification code: 123f296909305f1f677a5e15620c746326      Your balance: 1000, 18 transactions left.      Command: create 9999      Too many transactions or amount too big!      Your balance: 1000, 18 transactions left.   We need to have a million or more in 'your balance' and seems that it's impossible to create transactions of 9999$ or more   let's check how it's done in the code       class Transaction:  	def __init__(self, a):  		self.__a = a  		self.__k = int(os.urandom(32).encode('hex'),16)  		self.__v = True  	[......]   class Transaction is created after we type command 'create' and it remembers the amount of money in __a   below is a fragment of code from command handled   		  elif("complete" in cmd):  			  [.......]  			  if(len(h) != 34):  				  print 'Wrong verification length'  				  continue  			  tn = A.get_t()[t]     #get transaction of number t  			  tn = C.decrypt(tn, h) #decryption: tn - transaction, h - verification code  			  if(tn is None):  				  print 'Oops, verification failed!'  				  continue  			  r = A.add_m(tn)       #adding money to account   we see that amount of added money to account is based on decrypted value, so let's investigate how encryption and decryption is done and check how to avoid 'verification failed'  
	  def encrypt(self, t): # t is object of class Transaction		self.__r.set_x(t.get_k())		ct = ""		s = str(t) #(1)		l = len(s)		s += chr(0x09)*(17-l) #(2)		for c in s:			ct += chr( ord(c) ^ (self.__r.get_next() % 2**7) ) #(3)		return ct.encode('hex')
	def decrypt(self, t, ct): # t - transaction ct - verification code		self.__r.set_x(t.get_k())		try:			ct = ct.decode('hex')			pt = ""			for c in ct:				pt += chr( ord(c) ^ (self.__r.get_next() % 2**7) )			if(not "TRANSACTION" in pt):				return None			a = int(pt.replace("TRANSACTION:",""))			t.set_a(a)			return t		except:			return None the text is simply xor'ed with bytes generated by the class Randomizer  function encrypt get's a text value of object of class Transaction (1)  adds padding 0x09 where length is too small (2)  and xor's this text (3)  
this text value of object looks like "TRANSACTION: 1000"  we can see this in below code:  
    class Transaction:        [....]        def __str__(self):		return "TRANSACTION: " + str(self.__a) function decrypt is checking if transaction code is correct by checking of presence of text "TRANSACTION:" in the decrypted value  
encrypted text looks like 'T' xor'ed with something, 'r' xor'ed with something2, 'a' xored with something3 and so on...  
on the position 13 we have '1' xor x1 , 14 - '0' xor x2, 15 -'0' xor x3, 16 - '0' xor x4.  We can xor position 13 with '1' and after that xor with '9' and position 14 with '0' and '9' and so on  
('1' xor x1) xor '1' xor '9' = x1 xor '9'  
so we can change 1000 to 9999  
but 9999*20 is still lower than million and we can't make verification code longer  
but seems like we can also change space between ':' and a value to some number because only "TRANSACTION:" is removed before casting decrypted value to integer so let's change space also to '9' using same method as above  
I created a code which changes verification code of value 1000 to code with value 99999  
![bank_solv.py](bank_solv.py)
we need to create ~11 transaction  
