Replay attack on CAPTCHA Libraries Summary A CAPTCHA implementation that we tested were found to be vulnerable to replay attacks. The attack is explained in detail for Formshield � A popular DOT NET CAPTCHA implementation. NOTE: We discovered this during a Black Box engagement with one of our clients. The version which is vulnerable is an older version of Formshield ; the exact version is not clear. The developer claims that the problem has been fixed in the newest version of Formshield. Here is the explanation of the Formshield attack in detail: =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ The Formshield CAPTCHA library that is used to prevent automated bots from functioning is vulnerable to a replay attack. It is possible to fix the CAPTCHA value to a specific value and send that value to the server as part of every request and gain access to protected resources. The Formshield CAPTCHA uses a dynamic key stored in the __VIEWSTATE of the request and sends encrypted text to the server for obtaining and displaying new image text in the CAPTCHA on the page every time. There are 2 problems with this approach: The encrypted text for a specific image always remains the same The key used to encrypt the request sent to the server does not expire Objective of the Attacks We intend to demonstrate that it is possible to preset the image text in a displayed CAPTCHA for every request thereafter. This image text can thereafter be used in every subsequent valid request to the application. Access to resources protected by the CAPTCHA can be obtained in the process. An adversary could create a program which will automate numerous form submissions and replay numerous requests all with the known preset CAPTCHA thus defeating the basic purpose of the CAPTCHA itself. Background A request for the initial page on which the Formshield Captcha is embedded is made. After all the other form fields on the page are rendered a separate request is made to the server to obtain the text for the Captcha image. This request contains 2 parameters: __formshield and properties. The value of the __formshield parameter was always found to be Formshield1. The value of the properties parameter changed each time new text was populated in the CAPTCHA image. Changing content of this parameter results in no new text being generated at all. The encrypted properties value though is obtained by a dynamic key in the __VIEWSTATE variable. If the contents of the __VIEWSTATE variable can be obtained then we have a plaintext cipher text match which can be replayed every time for every new request. Details of the Attack To carry out this attack we need to intercept and modify HTTP(S) traffic going to the web server. When the request for the CAPTCHA text is made the encrypted properties value is replaced with the known Ciphertext value instead. This results in the known plain text Captcha being set on the screen. The form is filled up and submitted along with the known plaintext CAPTCHA. Here is an example of the encrypted properties value that is sent and the image text that is displayed on screen. ENCRYPTED PROPERTIES VALUE: vQzTYzbknujZ52Q9KC6bf8k0DKljxksYExQwIiMYjF2rRfexAtdXbfDJp2ftmWE%2fNSqypLhRbhwRTcKowQ592KNf%2f4vXj%2fWJ4iW2vR%2fkd3FYwGZR4uwRW PAogFTvHZP8JoHX83PKoGnUv3pBoW23Tl2%2b9VeK63FeYtSaUbh7Ezebstd6VVmwEcEi%2bz8Gax5KVsTulQdVwVjXNtqEG9HbAQfAZUETWrzb%2fqc60O8r3j3M2BnRh%2fRJrgFAydv7GWp1vYpLAeUcrc%2f3FeuybntAalXPgxijb%2fMhNtA1TLOsheM8oZwpDq6fdA%3d%3d CORRESPONDING IMAGE TEXT: 91KG1a This request is once again intercepted and the __VIEWSTATE variable is replaced with the corresponding known __VIEWSTATE which contained the dynamic key. This modified request is then sent to the server which validates the CAPTCHA and offers access to protected resources. Since the imagetext-cipher text-__VIEWSTATE never expires we can submit the same request even after many days with the same values and it still succeeds. Solution: The problem can be mitigated by Managing the CAPTCHA value at the application server instead of the client side __VIEWSTATE variable by tying it to the Session ID. A 10 or 15 minute timeout if implemented improves the security as well. The image cache on the server side must also be expired as soon as it is rendered to the browser. =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ While the advisory mentioned here targets only a specific CAPTCHA this could well be a problem with any CAPTCHA implementation which does not verify the CAPTCHA code at the server side. All CAPTCHA developers can read this advisory and check their implementations to see whether this applies to them. Here is the URL for Formshield: Formshield � http://dotnetfreak.co.uk Arvind