From 7a89ae6f17548668575b47a0e97dd564502d3df1 Mon Sep 17 00:00:00 2001 From: cktricky Date: Sun, 16 Mar 2014 22:10:19 -0400 Subject: [PATCH] added the tutorial for the newest logic flaw --- app/models/pay.rb | 2 +- .../_insecure_crypto_reuse.html.erb | 72 +++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/app/models/pay.rb b/app/models/pay.rb index 74116a3..78f0278 100644 --- a/app/models/pay.rb +++ b/app/models/pay.rb @@ -11,7 +11,7 @@ class Pay < ActiveRecord::Base validates :bank_routing_num, presence: true validates :percent_of_deposit, presence: true - # actions + # callbacks before_save :encrypt_bank_account_num def as_json diff --git a/app/views/layouts/tutorial/logic_flaws/_insecure_crypto_reuse.html.erb b/app/views/layouts/tutorial/logic_flaws/_insecure_crypto_reuse.html.erb index d7ce9f3..c9e9e53 100644 --- a/app/views/layouts/tutorial/logic_flaws/_insecure_crypto_reuse.html.erb +++ b/app/views/layouts/tutorial/logic_flaws/_insecure_crypto_reuse.html.erb @@ -16,7 +16,9 @@
- insert desc +

+ The Railsgoat application allows employees of Metacorp to choose the Remember Me option at login, which creates a cookie named auth-token. The encryption routine used to generate the auth-token allows the application to extract a user ID. When decrypted, a user ID is extracted and the user is authorized appropriately. This same encryption routine is used elsewhere in the application in a manner such that a clever attacker can generate an auth_token cookie with whatever user ID they prefer and authorize to the application as a different user. +

@@ -30,7 +32,63 @@
- insert bug info +

+ Within the file lib/encryption.rb, there are two encryption related methods that we have exposed: +

+
+				  # Added a re-usable encryption routine, shouldn't be an issue!
+				  def self.encrypt_sensitive_value(val="")
+				     aes = OpenSSL::Cipher::Cipher.new(cipher_type)
+				     aes.encrypt
+				     aes.key = key
+				     aes.iv = iv if iv != nil
+				     new_val = aes.update("#{val}") + aes.final
+				     Base64.strict_encode64(new_val).encode('utf-8')
+				  end
+
+				  def self.decrypt_sensitive_value(val="")
+				     aes = OpenSSL::Cipher::Cipher.new(cipher_type)
+				     aes.decrypt
+				     aes.key = key
+				     aes.iv = iv if iv != nil
+				     decoded = Base64.strict_decode64("#{val}")
+				     aes.update("#{decoded}") + aes.final
+				  end
+				
+

+ We have placed this code under the lib directory so that we have a re-usable encryption routine. This code is used to generate a user's auth_token cookie responsible for authorization and access. However, we've also used this same code when encrypting a user's bank account number. This means, a user can enter in any value they would like and will receive it's encrypted equivalent back from the application. Essentially, a user has the ability to generate the auth_token cookie for any user ID and authorize as that user.

+ Within the app/models/pay.rb file we have a before hook that will save a user's bank account number as an encrypted value: +

+
+				  # callbacks
+				  before_save :encrypt_bank_account_num
+					
+				  def encrypt_bank_account_num
+				  	self.bank_account_num = Encryption.encrypt_sensitive_value(self.bank_account_num)
+				  end
+				
+

+ Additionally, we render that encrypted value (purposefully) when the show action is created within the app/controllers/pay_controller.rb file: +

+
+				   def show
+				   	respond_to do |format|
+				   	  format.json { render :json => {:user => current_user.pay.as_json} }
+				   	end
+				  end
+				
+

+ Lastly, we re-use this same routine within the following code is used to create a user's auth_token cookie upon sign-up or creation (app/models/user.rb): +

+
+					before_create { generate_token(:auth_token) }
+					
+				   def generate_token(column)
+				   	begin
+				   		self[column] = Encryption.encrypt_sensitive_value(self.user_id)
+				   	end while User.exists?(column => self[column])
+				   end
+				
@@ -45,9 +103,13 @@

Insecure Encryption Re-use ATTACK:

- insert attack +

+ Navigate to the Pay section of the application. Enter your bank account number but use the number 1 as your bank account number. Once the information is entered and submitted, you'll see the encrypted value of your bank account number (1) returned. URL encode the special characters (+ and ==) and use this value as your auth_token cookie. Navigate to your dashboard and you'll have the ability to access administrative functionality. +

Insecure Encryption Re-use SOLUTION:

- insert solution +

+ Create an entirely new encryption routine or create the SHA1 hash with a different salt. +

@@ -61,7 +123,7 @@
- insert hint + My "Remember Me" cookie looks familiar, almost like one of those values you get when you enter your bank account number.