Showing posts with label Security Code Review. Show all posts
Showing posts with label Security Code Review. Show all posts

03/05/2021

Solidity Smart Contract Upgradeability

Introduction 

This article is going to focus on Smart Contract upgradability, why this important and how can we achieve it. When dealing with Smart Contracts we need to be able to upgrade our system code. This is because if security critical bugs appear , we should be able to remediate the bugs. We would also want to enhance the code and add more features. Smart Contract upgradability is not as simple as upgrading a normal software due to the blockchain immutability.
 
As already mentioned by design, smart contracts are immutable. On the other hand, software quality heavily depends on the ability to upgrade and patch source code in order to produce iterative releases. Even though blockchain based software profits significantly from the technology’s immutability, still a certain degree of mutability is needed for bug fixing and potential product improvements.
 

Preparing for Upgrades   

In order to properly do the upgrade we should be focusing in the following aspects of the project:
  • Have money management strategies in place
  • Create a pause functionality 
  • Have paths to upgrades
    • Switching addresses
    • Switching Oracles
    • Proxy contracts 

The mentioned functionality is mandatory in order to properly maintain and do risk management on your system. The money management strategy has to do with were and how we hold the funds and the system data. The switch address is related to the proxy contract and the rest have to do with the flow paths we designed to upgrade the smart contracts [1]. 


Proxy Contract

The basic idea is using a proxy for upgrades. The first contract is a simple wrapper or "proxy" which users interact with directly and is in charge of forwarding transactions to and from the second contract, which contains the logic. The key concept to understand is that the logic contract can be replaced while the proxy, or the access point is never changed. Both contracts are still immutable in the sense that their code cannot be changed, but the logic contract can simply be swapped by another contract. The wrapper can thus point to a different logic implementation and in doing so, the software is "upgraded"


Note: This abstract proxy contract provides a fallback function that delegates all calls to another contract using the EVM instruction delegatecall. We refer to the second contract as the implementation behind the proxy, and it has to be specified by overriding the virtual _implementation function. Additionally, delegation to the implementation can be triggered manually through the _fallback function, or to a different contract through the _delegate function. 

The most immediate problem that proxies need to solve is how the proxy exposes the entire interface of the logic contract without requiring a one to one mapping of the entire logic contract’s interface. That would be difficult to maintain, prone to errors, and would make the interface itself not upgradeable. Hence, a dynamic forwarding mechanism is required [1].

Proxy Setup

Below we can see that the contract proxy has one to one relationship with all the logic contract proxy. An this is important in order to understand that this setup kind of breaks the immutability of the blockchain.
 

References:



16/03/2021

Ethereum Smart Contract Source Code Review

 Introduction 

As Crypto currency technologies are becoming more and more prevalent, as the time is passing by, and banks will soon start adopting them. Ethereum blockchain and other complex blockchain programs are relatively new and highly experimental. Therefore, we should expect constant changes in the security landscape, as new bugs and security risks are discovered, and new best practices are developed [1].This article is going to discuss how to perform a source code review in Ethereum Smart Contracts (SCs) and what to look for. More specifically we are going to focus in specific keywords and how to analyse them. 

The points analysed are going to be:
  • User supplied input filtering, when interacting directly with SC
  • Interfacing with external SCs
  • Interfacing with DApp applications
  • SC formal verification
  • Wallet authentication in DApp

SC Programming Mindset

When designing an SC ecosystem (a group of SCs, constitutes an ecosystem) is it wise to have some specific concepts and security design principles in mind. SC programming requires a different engineering mindset than we may be used to. The cost of failure can be high, and change can be difficult, making it in some ways more similar to hardware programming or financial services programming than web or mobile development. 

When programming SCs we should be able to:
  • Design carefully roll outs
  • Keep contracts simple and modular
  • Be fully aware of blockchain properties
  • Prepare for failure

Key Security Concepts For SCs Systems


More specifically it is mandatory and the responsible thing to  is to take into consideration the following areas:
  • SC ecosystem monitoring e.g. monitor for unusual transactions etc.
  • SC ecosystem governance/admin e.g. by using proxy SC that follow best practices etc.
  • SC formal verification of all the SCs interacting with
  • SC modular/clean coding e.g. use comments and modular code etc. 
  • SC ecosystem code auditing by an external independent 3rd party
  • SC ecosystem system penetration testing by an external independent 3rd party  
Note: At this point we should point out that it is important that DApp smart contract interaction should also be reviewed.

SCs User Input Validation

Make sure you apply user input validation on a DApp and SC level. Remember that on-chain data are public and an adversary can interact with a SC directly, by simply visiting an Ethereum explorer in etherscan.io, the following screenshots demonstrate that.

Below we can see an example of a deployed contract:



Simple by clicking in the SC link we can interact with the contract:



Note:  Above we can see the upgrade function call and various other Admin functions. Of course is not that easy to interact with them.

It is also known that etherscan.io provides some experimental features to decompile the SC code:


 If we click the decompile code we get this screen below:


Below we can see how a DApp or wallet can interact with a SC:



There are five categories of Ethereum wallets that can interact with DApps:
  • Browser built-in (e.g. Opera, Brave etc)
  • Browser extension (e.g. MetaMask )
  • Mobile wallets (e.g. Trust, Walleth, Pillar etc.)
  • Account-based web wallets (e.g. Fortmatic, 3box etc.)
  • Hardware wallets (e.g. Ledger, Trezor etc.)
Then there is a larger category of wallets that cannot integrate with DApps include generic wallet apps that lack the functionality to integrate with smart contracts. Different wallets have a different user experience to connect. For example, with MetaMask you get a Connect pop up. With mobile wallets, you scan a QR code. So phishing attacks take a different for e.g. an attacker can spoof a QR code, through online free QR generators etc. When assessing a DApp the architecture is of paramount importance. A user with a Metamask plugin can use it to connect to the DApp. The DApp automatically will associate the interaction with the user public key to run various tasks. 

For a Web based DApp we can use traditional filtering methods. But for SCs using Solidity we can use assert and require are as convenience functions that check for conditions (e.g. a user supplies input and the mentioned functions check if the conditions are met). In cases when conditions are not met, they throw exceptions, that we help us handle the errors.

These are the cases when Solidity creates assert-type of exceptions when we [3]:
  • Invoke Solidity assert with an argument, showing false.
  • Invoke a zero-initialized variable of an internal function type.
  • Convert a large or negative value to enum.
  • We divide or modulo by zero.
  • We access an array in an index that is too big or negative.
The require Solidity function guarantees validity of conditions that cannot be detected before execution. It checks inputs, contract state variables and return values from calls to external contracts.

In the following cases, Solidity triggers a require-type of exception when [3]:
  • We call require with arguments that result in false.
  • A function called through a message does not end properly.
  • We create a contract with new keyword and the process does not end properly.
  • We target a codeless contract with an external function.
  • We contract gets Ether through a public getter function.
  • We .transfer() ends in failure.
Generally speaking when handling complex user input and run mathematical calculations it is mandatory to use external libraries from 3rd partyaudited code. A code project to look into would be SafeMath from OpenZeppelin. SafeMath is a wrapper over Solidity’s arithmetic operations with added overflow checks. Arithmetic operations in Solidity wrap on overflow. This can easily result in bugs, because programmers usually assume that an overflow raises an error, which is the standard behavior in high level programming languages. SafeMath restores this intuition by reverting the transaction when an operation overflows.

SC External Calls


Calls to untrusted 3rd party Smart Contracts can introduce several security issues. External calls may execute malicious code in that contract or any other contract that it depends upon. As such, every external call should be treated as a potential security risk.  Solidity's call function is a low-level interface for sending a message to an SC. It returns false if the subcall encounters an exception, otherwise it returns true. There is no notion of a legal call, if it compiles, it's valid Solidity.


Especially when the return value of a message call is not checked, execution will resume even if the called contract throws an exception. If the call fails accidentally or an attacker forces the call to fail, this may cause unexpected behavior in the subsequent program logic. Always make sure to handle the possibility that the call will fail by checking the return value of that function [4].

Reentrancy (Recursive Call Attack)

One of the major risks of calling external contracts is that they can take over the control flow. In the reentrancy attack (a.k.a. recursive call attack) calling external contracts can take over the control flow, and make changes to your data that the calling function wasn’t expecting. A reentrancy attack occurs when the attacker drains funds from the target contract by recursively calling the target’s withdraw function [4].

Below we can see a schematic representation:




Note: For more information on this type of attack please see [4]

SC Denial of Service Attacks

Each block has an upper bound on the amount of gas that can be spent, and thus the amount computation that can be done. This is the Block Gas Limit. If the gas spent exceeds this limit, the transaction will fail. 

This leads to a couple possible Denial of Service vectors:
  • Gas Limit DoS on a Contract via Unbounded Operations
  • Gas Limit DoS on the Network via Block Stuffing
Note: For more information on DoS attacks see consensys.github.io

Use Of Delegatecall/Callcode and Libraries

According the Solidity docs [7], there exists a special variant of a message call, named delegatecall which is identical to a message call apart from the fact that the code at the target address is executed in the context of the calling contract and msg.sender and msg.value do not change their values.

This means that a contract can dynamically load code from a different address at runtime. Storage, current address and balance still refer to the calling contract, only the code is taken from the called address. This makes it possible to implement the “library” feature in Solidity: Reusable library code that can be applied to a contract’s storage, e.g. in order to implement a complex data structure.

Improper security use of this function was the cause for the Parity Multisig Wallet hack in 2017. This function is very useful for granting our contract the ability to make calls on other contracts, as if that code were a part of our own contract. However, using delegatecall() causes all public functions from the called contract to be callable by anyone. Because this behavior was not recognized when Parity built its own custom libraries. 

Epilogue 

Writing secure smart code is a lot of work and can be very complex.

References:


28/05/2016

Hacker’s Elusive Thoughts The Web

Introduction

The reason for this blog post is to advertise my book. First of all I would like to thank all the readers of my blog for the support and feedback on making my articles better. After 12+ years in the penetration testing industry, the time has come for me to publish my book and tranfer my knowledge to all the intersted people that like hacking and want to learn as much as possible. Also at the end of the blog you will find a sample chapter.



About The Author

Gerasimos is a security consultant holding a MSc in Information Security, a CREST (CRT), a CISSP, an ITILv3, a GIAC GPEN and a GIAC GAWPT accreditation. Working alongside diverse and highly skilled teams Gerasi- mos has been involved in countless comprehensive security tests and web application secure development engagements for global web applications and network platforms, counting more than 14 years in the web application and application security architecture.

Gerasimos further progressing in his career has participated in vari- ous projects providing leadership and accountability for assigned IT security projects, security assurance activities, technical security reviews and assess- ments and conducted validations and technical security testing against pre- production systems as part of overall validations.

Where From You Can Buy The Book

This book can be bought from leanbup. Leanpub is a unique publishing platform that provides a way in the world to write, publish and sell in-progress and completed ebooks. Anyone can sign up for free and use Leanpub's writing and publishing tools to produce a book and put it up for sale in our bookstore with one click. Authors are paid a royalty of 90% minus 50 cents per transaction with no constraints: they own their work and can sell it elsewhere for any price.

Authors and publishers can also upload books they have created using their own preferred book production processes and then sell them in the Leanpub bookstore, taking advantage of our high royalty rates and our in-progress publishing features.

Please for more information about bying the book see link: https://leanpub.com/hackerselusivethoughtstheweb

Why I Wrote This Book

I wrote this book to share my knowledge with anyone that wants to learn about Web Application security, understand how to formalize a Web Appli- cation penetration test and build a Web Application penetration test team.

The main goal of the book is to: 

Brainstorm you with some interesting ideas and help you build a com- prehensive penetration testing framework, which you can easily use for your specific needs. Help you understand why you need to write your own tools. Gain a better understanding of some not so well documented attack techniques.
The main goal of the book is not to:
 
Provide you with a tool kit to perform Web Application penetration tests. Provide you with complex attacks that you will not be able to under- stand. Provide you with up to date information on latest attacks.

Who This Book Is For 


This book is written to help hacking enthusiasts to become better and stan- dardize their hacking methodologies and techniques so as to know clearly what to do and why when testing Web Applications. This book will also be very helpful to the following professionals:

1. Web Application developers.
2. Professional Penetration Testers.
3. Web Application Security Analysts.
4. Information Security professionals.
5. Hiring Application Security Managers.
6. Managing Information Security Consultants.

How This Book Is Organised  

Almost all chapters are written in such a way so as to not require you to read the chapters sequentially, in order to understand the concepts presented, although it is recommended to do so. The following section is going to give you an overview of the book:

Chapter 1: Formalising Web Application Penetration Tests -
This chapter is a gentle introduction to the world of penetration testing, and attempt to give a realistic view on the current landscape. More specifically it attempt to provide you information on how to compose a Pen- etration Testing team and make the team as ecient as possible and why writing tools and choosing the proper tools is important.

Chapter 2: Scanning With Class -

The second chapter focuses on helping you understand the dierence between automated and manual scanning from the tester’s perspective. It will show you how to write custom scanning tools with the use of Python. This part of the book also contains Python chunks of code demonstrating on how to write tools and design your own scanner.

Chapter 3: Payload Management -

This chapter focuses on explaining two things a) What is a Web payload from security perspective, b) Why is it important to obfuscated your payloads.

Chapter 4: Infiltrating Corporate Networks Using XXE -

This chapter focuses on explaining how to exploit and elevate an External Entity (XXE) Injection vulnerability. The main purpose of this chapter is not to show you how to exploit an XXE vulnerability, but to broaden your mind on how you can combine multiple vulnerabilities together to infiltrate your target using an XXE vulnerability as an example.

Chapter 5: Phishing Like A Boss -

This chapter focuses on explaining how to perform phishing attacks using social engineering and Web vulnerabilities. The main purpose of this chapter is to help you broaden your mind on how to combine multiple security issues, to perform phishing attacks.

Chapter 6: SQL Injection Fuzzing For Fun And Profit -

This chapter focuses on explaining how to perform and automate SQL injection attacks through obfuscation using Python. It also explains why SQL injection attacks happen and what is the risk of having them in your web applications.


Sample Chapter Download
From the following link you will be able to download a sample chapter from my book:

Sample Book Download
















17/04/2014

PHP Source Code Chunks of Insanity (Delete Post Pages) Part 4

Intro 

This post is going to talk about source code reviewing PHP and demonstrate how a relatively small chunk of code can cause you lots of problems.

The Code

In this article we are going to analyze the code displayed below. The code displayed below might seem innocent for some , but obviously is not. We are going to assume that is used by some web site to delete posts from the logged in users securely.
 <?php  
 require_once 'common.php';   
 validatemySession();   
 mydatabaseConnect();  
  $username = $_SESSION['username'];// Insecure source  
 $username = stripslashes($username);// Improper filtering  
 $username = mysql_real_escape_string($username);//Flawed function  
 // Delete the post that matches the postId ensuring that it was created by this user  
  $queryDelete = "DELETE FROM posts WHERE PostId = " . (int) $_GET['postId']. " AND Username = '$username'";  
  if (mysql_query($queryDelete))// Bad validation coding {  
       header('Location: myPosts.php'); }  
  else {  
      echo "An error has occurred.";   
      }  
 ?>  

If you look carefully the code you will se that the code is vulnerable to the following issue: SQL Injection!!
    
Think this is not accurate , think better.

The SQL Injection

An adversary in order to exploit this vulnerability would not have to script custom tools, would only have to have good knowledge of SQL injections methodologies and exposure to PHP coding.

Vulnerable Code:

1st Code Chunk 
 $username = $_SESSION['username'];// Insecure source  
 $username = stripslashes($username);// Improper filtering 
 $username = mysql_real_escape_string($username);//Flawed function  
2nd Code Chunk: 
 $queryDelete = "DELETE FROM posts WHERE PostId = " . (int) $_GET['postId']. " AND Username = '$username'";  
3rd Code Chunk:    
 if (mysql_query($queryDelete))  

The mysql_real_escape_string function is based in the black list mentality. What it does is that escapes special characters in the un-­‐escaped string, taking into account the current character set of the connection so that it is safe to place it in a mysql_query. More specifically mysql_real_escape_string calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters:

1. \x00 
2. \n
3. \r
4. \
5. '
6. “

7. \x1a.

Due to this odd behavior characters such as the % and SQL keywords are not being affected, so queries that have the form of e.g. SELECT BENCHMARK(50,MD5(CHAR(118))) would be executed normally. A realistic scenario would be to use a query such as the one below:

Step1: SQL Payload that would cause the post to delete without the postId be known. 
 LIKE %’s’  

Note1: At this point we assume that the attacker knows the format of the username e.g. its user plus a two-­‐digit number. 

Step2: SQL Payload mutated in order to bypass the filters.
 LIKE CHAR(37, 8217, 115, 8217)  

Note2: Further expanding on the attack if the Web App does not have a standard format for the usernames then the adversary can brute-­‐force the username first latter e.g. try out all English letters e.g. LIKE %’a’, LIKE %’b’, LIKE %’c’ ... etc. and eventually execute the query with a valid first username letter. Translating that to an obfuscated SQL Payload would be LIKE CHAR(39, 97, 37, 39), LIKE CHAR(39, 98, 37, 39) etc.

Note3: The mysql_real_escape_string function is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. Alternatives to this function include: mysqli_real_escape_string and PDO::quote. The mysql_query() function sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier. In this specific code example the query returns true if a record is found (any record). This obscure behavior introduces the vulnerability combined of course with the above code. The function used in the mysql_query statement should return a record set only if the correct record set is returned and not just any match.

Note4: This extension is deprecated as of PHP 5.5.0.

Remedial Code:

Provide Server Side filters filter for remediating the vulnerability. Make use of strongly typed parameterized queries (using the bind_param).
 // Using prepared Statements.  
 if ($stmt = $mysqli-­‐>prepare("DELETE FROM posts WHERE PostId = ? AND Username = ? LIMIT 1"))  
 {  
 $stmt-­‐>bind_param('s', $ username); // Bind "$ username" to parameter. 
 $stmt-­‐>execute(); // Execute the prepared statement.  
 ...  
 }  

15/04/2014

PHP Source Code Chunks of Insanity (Post Pages) Part 3

Intro 

This post is going to talk about source code reviewing PHP and demonstrate how a relatively small chunk of code can cause you lots of problems.

The Code

In this article we are going to analyze the code displayed below. The code displayed below might seem innocent for some , but obviously is not. We are going to assume that is used by some web site to post the user comments securely.
<?php require_once 'common.php'; validateMySession(); ?> <html> <head> <title>User Posts</title> </head> <body> <h1>Showing current posts</h1> <form action='awsomePosts.php'>
<p>MySearch: <input type='text'  value='<?php if (isset($_GET['search'])) echo htmlentities($_GET['search'])?>'></p> <p><input type='submit' value='MySearch'></p>
</form> <?php showAwsomePosts();?> </body>
</html>
If you look carefully the code you will se that the code is vulnerable to the following issue: Stored XSS!!
    
Think this is not accurate , think better.

The Stored XSS

An adversary would need to have very good knowledge of encoding/XSS attacks to exploit this vulnerability. This vulnerability is based on a well known UTF-­‐7 encoding attack that is considered to be old. Other filter bypassing techniques can be used to bypass htmlentities such as JavaScript events.

Vulnerable Code: 
1:  <p>MySearch: <input type='text' value='<?php if (isset($_GET['search'])) echo htmlentities($_GET['search'])?>'></p>// Vulnerable to XSS UTF-­‐7 attack  
The page that the potential XSS resides on doesn't provide a page charset header (e.g. header('Content-­‐ Type: text/html; charset=UTF-­‐8'); or <HEAD><META HTTP-­‐EQUIV="CONTENT-­‐TYPE" CONTENT="text/html; charset=UTF-­‐8">), any browser that is set to UTF-­‐7 encoding can be exploited with the following XSS input (she don't need the charset statement if the user's browser is set to auto-­‐ detect and there is no overriding content-­‐types on the page in Internet Explorer and Netscape rendering engine mode). This does not work in any modern browser without changing the encoding type.

Example1 UTF-­‐7 Encoding

Input Payload :

1:  <script>alert(1)</script>  

Output (UTF-­‐7): 
1:  +ADw-­‐script+AD4-­‐alert('XSS')+ADw-­‐/script+AD4APA-­‐/vulnerable+AD4-­‐  

Example2 JavaScript Events

Injecting also JavaScript events to the htmlentities function of php will also by pass the filter.

The code before injection:     
1<p>MySearch: <input type='text' value='<?php if (isset($_GET['search'])) echo htmlentities($_GET['search'])?>'></p>  

The code after injection:
<p>MySearch: <input type='text' value='onerror='alert(String.fromCharCode(88, 83, 83))'></p>  


Note: This example needs further testing to see if it is applicable.

Remedial Code:

Provide Server Side filters for the vulnerability. Make use of regular expressions and html encode the variables whether displayed back to the user or not.

1st Layer of defense 
1:  //XSS filter the value because this value might be printed later on back in the user. if preg_match ("/[a-­‐zA-­‐Z]+/", "", $search){  
2:  showPosts();  
3:  }  
Note: Using regular expressions to replace parts of the input and proceed with further processing the input is not recommended, once a malicious input is identified should be rejected (e.g. using preg_match instead of preg_replace).

2nd Layer of defense 
1:  header('Content-­‐Type: text/html; charset=UTF-­‐8');  
2:  // This function will convert both double and single quotes. mb_convert_encoding($search, 'UTF-­‐8');  


Countermeasures Summarized
  1. Specify charset clearly (HTTP header is recommended)
  2. Don't place the text attacker can control before <meta>
  3. Specify recognizable charset name by browser.
  4. Apply regular expressions based on the white list mentality.
Note: mb_convert_encoding converts the character encoding of the input string to the desired encoding. 

References:

1. https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#UTF-­‐7_encoding 
2. http://php.net/manual/en/function.mb-­‐convert-­‐encoding.php
3. http://shiflett.org/blog/2005/dec/google-­‐xss-­‐example
4. http://www.motobit.com/util/charset-­‐codepage-­‐conversion.asp
5. http://openmya.hacker.jp/hasegawa/security/utf7cs.html 
6. http://wiremask.eu/?p=tutorials&id=10 


PHP Source Code Chunks of Insanity (Logout Pages) Part 2

Intro 

This post is going to talk about source code reviewing PHP and demonstrate how a relatively small chunk of code can cause you lots of problems.

The Code

In this article we are going to analyze the code displayed below. The code displayed below might seem innocent for some , but obviously is not. We are going to assume that is used by some web site to de-validate the user credentials and allow the users to logout securely.

1:  <?php  
2:  require_once 'common.php';  
3:  if (isset($_SESSION['username']))//Insecure source  
4:  {  
5:  session_unset();// In properly destroyed session.  
6:  }  
7:  header('Location: index.php'); ?>  


I you look carefully the code you will se that the code is vulnerable to the following issues:
  1. NULL De-­Authentication Bypass    
  2. No Proper Session Termination    
Think this is not accurate , think better.

NULL De-­Authentication Bypass 

Exploitation:

An adversary may on purpose exploit this vulnerability possibly without the need of developing any costume tools (but needs a good understanding of PHP design flaws). More specifically an adversary can manipulate the cookie parameter and de-­‐validate the logout process by injecting a NULL value in the begging of the username (after the authentication). This would result into maintaining the user Web resources available for the specific session-­‐id even after the logout is performed. 

Vulnerable Code:    
if (isset($_SESSION['username']))// Malicious de-­validation cancel  
Assuming that the target username is user12 potential malicious payloads that could exploit the vulnerability displayed above would be user[space]12 , %4e%55%4c%4c,user12, user12[space], %20user12, [space] [space]user12 [space],user12 , user12, user12,, user12NULL NULLuser12 etc. This is applicable due to the fact that if multiple parameters are supplied then the isset will return TRUE only if all of the parameters are set. Evaluation goes from left to right and stops as soon as an unset variable is encountered. The attack should occur after the user successfully authenticates her self.

Note1: At this point it should be noted that when on, register_globals (which is on by default in PHP < 5.3.0), will allow an adversary to populate the cookie username variable from various user input such request variables from HTML hidden form fields, Web Application URL’s etc. which translates into working as a vulnerability amplifier! Also this might lead into allowing POST to GET interchanges, promoting CSRF like attacks (e.g. the web app does not distinguish POST from GET).

Note2: This feature has been DEPRECATED as of PHP 5.3.0 and REMOVED as of PHP 5.4.0. 

Remedial Code:
1:  //the filter makes sure the username has no spaces. if (strpos($username, " ") !== false){  
2:  // De-­‐validate the session  
3:  }  

2nd Code Chunk:
1:  trim("^$", $username)//Not recommended to process malicious payloads, only identify.  

Note: The NULL value translates into an empty string when validations come. 

No Proper Session Termination

An adversary may on purpose exploit this vulnerability without the need of developing any costume tools. This attack might be used to perform vertical/horizontal user escalation (e.g. the cookie session-­‐ id is assigned to a new user, and the new user automatically gains access to previous user Web resources, assuming that the Web Apps makes access control decisions by using only the session-­‐id. Another attack scenario would be that the session is leaked though a blog post and the adversary makes use of the non de-­‐validated leaked session to gain access to the Web Application user resources etc.).

Vulnerable Code: 
1:  session_unset(); // Improper handling of the session.  
Note1: The function shown above does not properly de-­‐validate the session. The session_unset function just clears the $_SESSION variable. It’s equivalent to doing $_SESSION = array(); So this does only affect the local $_SESSION variable instance, but not the session data in the session storage, everything else remains unchanged (including the session identifier). In this occasion the session_unset is used to destroy/reset the session instead of the session_destroy function in the logout page. The session_destroy() function destroys all of the data associated with the current session.

Note2: The variable session_unset is considered to be deprecated code that does not use $_SESSION.

Remedial Code: 
1:  function destroySession() {  
2:  $params = session_get_cookie_params(); setcookie(session_name(), '', time() -­‐ 42000,  
3:  $params["path"], $params["domain"],  
4:  ... );  
5:  session_destroy(); }  




References:

1. http://php.net/manual/en/security.globals.php
2. https://www.owasp.org/index.php/Unvalidated_Input
3. http://php.net/manual/en/function.isset.php
4. http://php.net/manual/en/function.trim.php 

14/04/2014

PHP Source Code Chunks of Insanity (Logins Pages) Part 1

Intro 

This post is going to talk about source code reviewing PHP and demonstrate how a relatively small chunk of code can cause you lots of problems.

The Code

In this article we are going to analyze the code displayed below. The code displayed below might seem innocent for some , but obviously is not. We are going to assume that is used by some web site to validate the credentials and allow the users to login.

 <?php  
     require_once 'commonFunctionality.php';  
        if (validateCredentials($someUsername, $somePassword)) {  
           header('Location: myIndex.php'); }  
        else {  
           header('Location: wrong_login.php'); }  
 ?>  

If you look carefully the code you will se that the code is vulnerable to the following issues:
  1. Reflected/Stored XSS
  2. Session Fixation/Session Hijacking 
  3. Lock Out Mechanism Not In Place
Think this is not accurate , think better.

Session Fixation/Session Hijacking

An adversary may on purpose exploit this vulnerability without the need of developing any costume tools (e.g. the session gets exposed in a blog post or within the same application or is passed in the http referrer and gets cached in a Web Proxy controlled by an adversary). Also this attack might be used to abuse user privileges (e.g. escalate privileges of one user by manipulating the session identifier, perform vertical and horizontal privilege escalation etc.). It should be noted at this point that the issues described above are possible only if the web application makes decisions based only on the session identifier.

Vulnerable Code:
session_unset(); // Improper handling of the session.  

Explanation:

The function shown above does not properly handle the session. The session_unset function just clears the $_SESSION variable. It’s equivalent to doing $_SESSION = array(); So this does only affect the local $_SESSION variable instance, but not the session data in the session storage, everything else remains unchanged, including the session identifier. In this occasion the session_unset is used to clear the session from user information, instead of the session_destroy function in the login page (instead of the logout page), which translates into not logging out properly the previous user (e.g. the next user will possibly again access to the account of the previous user).The Web Application makes decisions without evaluating other cookie parameters to give access to Web Resources (e.g. the decision making process is the username, a variable called logged_in and the session id). Ideally this should partly be fixed by using also another variable e.g. $_SESSION[‘logged_in’] = true (see code below). 

Exploitation:

An adversary may on purpose exploit this vulnerability without the need of developing any costume tools (e.g. the session gets exposed in a blog post or within the same application or is passed in the http referrer and gets cached in a Web Proxy controlled by an adversary). Also this attack might be used to abuse user privileges (e.g. escalate privileges of one user by manipulating the session identifier, perform vertical and horizontal privilege escalation etc.). It should be noted at this point that the issues described above are possible only if the web application makes decisions based only on the session identifier.

Business Impact:

The possibility of this vulnerability going public (e.g. blog posts start appearing in the internet revealing the issue) would cause severe costumer reputation and revenue loss; this vulnerability allows an adversary to potentially launch personalized phishing attacks (e.g. deceive a user in clicking a link with a fixed session etc.) abuse web application user privileges and possibly allow phishing campaigns. 

Remedial Code: 
 function init_session() { ...  
 session_start(); // Start the php session  
 session_regenerate_id(true); // regenerated the session, delete the old one. $_SESSION['logged_in'] = true;  
 ... }  
Regenerate the session ID anytime the session's status changes. That means any of the following:
  1. User authentication (e.g. in the login page, other multiple authentication stages etc.).
  2. Storing privilege level information in the session (e.g. temporary random variables, valid only
    for the current session etc.)
  3. Regenerate the session identifier whenever the user's privilege level changes. 
Lock Out Mechanism Not In Place

An adversary may on purpose exploit this vulnerability without the need of developing any costume tools (e.g. make use of Burp Intruder or Hydra to perform online password cracking attacks etc.).

Vulnerable Code:

 $username = $_POST['username']; $password = $_POST['password'];  
Note: The Web Application should implement server side controls in the login page to prevent password brute forcing attacks.

Remedial Code:


 function lockout($username, $password) { $now = time();  
 $counter = 0  
 if (validateCredentials){  
 $counter = $counter+1// Save that in database, retrieve login attempt times and compare the  
 times ...  
 } }  

The Web Application should take the following actions to prevent online dictionary attacks:
  1. Make use of login attempt counters (e.g. allow 3 failed attempts within 30 minutes).
  2. Associate the user IP with the session (e.g. generate proper audit trails to later on ban that ip).
    Include the user's IP address from $_SERVER['REMOTE_ADDR'] in the session. Store it in
    $_SESSION['remote_ip'].
  3. Run integrity checks of the session (although this functionality might be included in another
    function).
  4. Include the user agent from $_SERVER['HTTP_USER_AGENT'] in the session. Store it in a session
    variable $_SESSION['user_agent']. Then, on each subsequent request check that it matches (Note: The user agent can be very easily spoofed). 
Note: It should also be noted that since the session parameters are also populated with sensitive information such as the username, further actions should be performed to remove all this information (e.g. replace username with temporary user-­‐id). Gaining access to the username can significantly reduce a brute-­‐force login attempt. 

Reflected/Stored XSS

An adversary can exploit this vulnerability without the need of developing any costume tools. Point and click tools are available in the Internet and might be used to exploit this vulnerability (e.g. Social Engineering Tool etc.). Further escalating on the issue an adversary might use this attack to compromise multiple company sites (e.g. make use of it as an XSS proxy).

Note: This might also lead into unrestricted redirection attacks. Due to limited amount of time in my disposal no further investigation was conducted (e.g. load the login page to an Apache as and see if the variable username is passed the URL or the location header field.) 

Vulnerable Code:
 $_SESSION['username'] = $username;  

Note: Even though we don’t have access to the rest of the Web App code, it is highly likely that the username value might be displayed back to the user and the Http header fields. 

Remedial Code: 

Provide Server Side filters for the vulnerability. Make use of regular expressions and html encode the variables whether displayed back to the user or not (for providing security in depth and making sure that the Set-­‐Cookie header field or other fields cannot be abused).

1st Layer of defense

 $username = preg_match ("/[^a-­‐zA-­‐Z0-­‐9_\-­‐]+/", "", $username)  

Note: Ideally the username should be replaced with a temporary user id (preferable random that expires along with the cookie session). Using regular expressions to replace parts of the input and proceed with further processing the input is not recommended, once a malicious input is identified should be rejected (e.g. using preg_replace instead of preg_match). Also note that this functionality should ideally be also part of the validateCredentials function or the input should be processed before used by the validateCredentials function. 

2nd Layer of defense


1. // This function will convert both double and single quotes. 
2. htmlentities($username , ENT_QUOTES);  

Input: 
 <script>alert(1)</script>   

Output:
 &#x3c;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3e;&#x61;&#x6c;&#x65;&#x72;&#x7 4;&#x28;&#x31;&#x29;&#x3c;&#x2f;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3e;  


Note: With htmlentities, all characters which have HTML character entity equivalents are translated into these entities (displayed above). 

References:

  1. https://www.owasp.org/index.php/Account_lockout_attack
  2. http://stackoverflow.com/questions/17217777/difference-­‐between-­‐unset-­‐and-­‐session-­‐unset-­‐ in-­‐php
  3. http://shiflett.org/articles/session-­‐fixation
  4. http://shiflett.org/articles/session-­‐hijacking