Sunday, September 04, 2011

Source Seattle 2011 - Video Up - Art of InfoJacking

In May , I presented about Art of InfoJacking in Source Seattle. The video can be seen here.

Wednesday, August 31, 2011

PenTest Magazine - Breaking Down i*{Devices} - Testing iPhone Security

Smartphones have revolutionized the world. The online world is grappling with severe security and privacy issues. The smartphone applications require an aggressive approach of security testing and integrity verification in order to serve the three metrics of security such as confidentiality, integrity and availability.

This paper sheds a light on the behavioral testing and security issues present in Apple’s IOS devices and applications. Primarily, this paper revolves around penetration testing of iPhone device and its applications. The paper does not discuss the iPhone application source code analysis and reverse engineering.

Download the magazine from : HERE

Thursday, August 25, 2011

Dissecting Java Server Faces for Penetration Testing

This paper sheds light on the findings of security testing of Java Server Faces. JSF has been widely used as an open source web framework for developing efficient applications using J2EE. JSF is compared with ASP.NET framework to unearth potential security flaws.

This paper is an outcome of my work at Cigital Labs. It is a collaborative work with Security Compass team.

Download :


Friday, August 19, 2011

User Agent / SSL Version and SSL2_READ_INTERNAL:bad mac decode

During SSL version verification and testing, one might encounter different issues on different platforms. The output greatly depends on the type of User agent is used and the SSL configuration parameters on server side. In certain scenarios, one might encounter SSL2_READ_INTERNAL:bad mac error while testing for SSLv2 on the server. For example: let's have a look the example below

[Request/Response - 1]

root@bt:~# curl -v -2 -k
* About to connect() to port 443 (#0)
* Trying ... connected
* Connected to port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv2, Client hello (1):
* SSLv2, Server hello (4):
* SSLv2, Client key (2):
* SSLv2, Client finished (3):
* error:140EC071:SSL routines:SSL2_READ_INTERNAL:bad mac decode
* Closing connection #0

root@bt:~# openssl s_client -connect -ssl2
depth=0 / Organization/serialNumber=2927442/C=US/postalCode=75202/ST=Texas/L=Dallas/streetAddress=1201 Main Street/O=Bank Corporation/OU=WebSphere Ecomm
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 / Organization/serialNumber=2927442/C=US/postalCode=75202/ST=Texas/L=Dallas/streetAddress=1201 Main Street/O= Bank/OU=WebSphere Ecomm
verify error:num=27:certificate not trusted
verify return:1
depth=0 / Organization/serialNumber=2927442/C=US/postalCode=75202/ST=Texas/L=Dallas/streetAddress=1201 Main Street/O=Bank /OU=WebSphere Ecomm
verify error:num=21:unable to verify the first certificate
verify return:1
2170:error:140EC071:SSL routines:SSL2_READ_INTERNAL:bad mac decode:s2_pkt.c:274:

[Request/Response - 2]
root@bt:~# curl -v -2 -k
* About to connect() to port 443 (#0)
* Trying ... connected
* Connected to ( port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv2, Client hello (1):
* Unknown SSL protocol error in connection to
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to

root@bt:~# openssl s_client -connect -ssl2
2179:error:1407F0E5:SSL routines:SSL2_WRITE:ssl handshake failure:s2_pkt.c:428:

The above presented response information is from the same target. The first request has "www" prefix appended to the domain name and second request is without "www" prefix.

The first case results in half handshake and server side verification fails. This error usually occurs when server detects a specific padding option chosen for the the protocol version (SSLv2 in this case). It typically looks like a Protocol Rollback Attack. The server only negotiates successfully when only SSLv2 is enabled on the server. However, hostname ( also plays a role because there is always a SSL redirection implemented on the server side.

The second case simply rejects the SSLv2 handshake. The hostname ( is used does not have "www" prefix. The point is while testing SSL version different errors should be fuzzed appropriately before raising a red flag.


Tuesday, August 16, 2011

LDAP Injection - CN /SN /UID /MAIL - Attack Payloads

LDAP injections are detected very less as compared to XSS attacks. However, every injection is critical from security point of view. Recently I came across one of the biggest educational university that has implemented LDAP for its directory services. With no reasonable doubt it was vulnerable to LDAP injections. It was fun to play around with it. For security purposes, I am not going to show the successful injection snapshots (figure it out yourself) but only present the payloads and brief queries.

It is the most common example of searching username in the directories. The website has search form with different name fields. On some HTTP debugging, the form is submitting these variables.

sn cn uid mail full 0 submit Search

Considering the set of variables, the most generic implementation of LDAP filter looks as presented below

One might encounter following errors

1. There was an error connecting to the server.Please try again.

2. You have not entered anything to search on. There were 0 matches to your query.
Please return to the search page to reformulate your query.

3. 500 Internal Server Error

4. Successful query

Attack payloads:

/cgi-bin/ldap/ldap_query.cgi?cn=*) (|(objectClass=person)
/cgi-bin/ldap/ldap_query.cgi?cn=*)(|(cn = * ))
/cgi-bin/ldap/ldap_query.cgi?cn=*)(|(uid = * ))

Meta Characters - ))|\\\\ |!@#$ &&

There are other set of payloads that can be used. The output of one of the injection looks like as presented below

Enjoy !

Monday, August 08, 2011

SQL Injection (Primer 2) - Collation / Case Insensitive and WAF bypassing

SQL injections are prevalent in all type of scenarios. With the advent of Web application Firewalls (WAF's) there are number of protection mechanisms that have been developed to prevent injections. WAF's are good solutions but these are not that good enough to prevent advanced level of SQL injections. However, during the course of my experience, I have noticed case sensitive / insensitive plays a critical role in designing bypasses.

The SQL queries are case insensitive. This feature of SQL databases (MySQL/ MSSQL)
helps a lot in designing WAF bypasses. The reason is, WAF's are mainly signature specific in most of cases which are explicitly written. By default, regular expressions are case sensitive. It is also possible to control case sensitivity within a pattern using the inline modifier (?i). However, it makes the signature really complex and hard to manage in certain scenarios. But this applied procedure is not hard to implement.

Note: The examples are taken from the real time websites and applications. The websites names have been masked for security purposes.

For example, the following SQL injection is usually filtered by the WAF in number of cases.,2,concat(Count(*)),4,5,6+from+information_schema.table_constraints--

The point is to break the filter at any one point so that whole of regular expression fails. The following code allows,2,CoNcaT(Count(*)),4,5,6+fRoM+information_schema.table_constraints--

In the above presented SQL injection, case sensitive approach is used to bypass WAF and at last case insensitive approach is exploited in order to render injection successfully. This injection can further by obfuscated using meta characters (/* ! */) , // , # +- , ; , # as pointed below*!+aNd*/+1=2+uNioN+aLl+sElecT+1,2,CoNcaT(Count(*)),4,5,6+fRoM+information_schema.table_constraints--

One can design plethora of combinations based on the above discussed specifications in order to test for SQL injections in different environments.

All the informational issues discussed above are usually due to case insensitive nature of databases. There is a way, one can write SQL queries that are case sensitive using Collation procedure in databases. You can check for collations here. However, this process depends on the application design. It is something that developers implement by choice or when it is critically required.

Follow this !

Saturday, August 06, 2011

SQL Injection (Primer 1) - PHP Escaping and Like Operators

This post talks about exploiting the SQL queries with LIKE operator in use. However, this situation and target can be specific in nature but one can use the concept that is discussed below to go after exploiting the SQL injection. In order to discuss this part, let's take an example as presented below

if (isset($_POST['submit_search'])){
$search_name = htmlentities(mysql_real_escape_string($_POST['search_user']));
$age = stripslashes($_POST['age']);

$query1 = mysql_query("SELECT * FROM user_table WHERE username LIKE '$search_user' AND age=('$age')") or die("SQL Error Mate");

In this example, "search_user" is the parameter that is provided as an initial input point to the application user. As one can see, this parameter is escaped using mysql_real_escape_string(escapes special characters in a string for use in an SQL statement) and then with htmlentities (convert all applicable characters to HTML entities). There is another parameter as "age" which is set with stripslashes(returns a string with backslashes stripped off)

So in this case, where the SQL injection can be done. Following consideration leads to successful SQL injection

1. There is an age parameter which takes the value from the application user. This parameter is expected by the server in the POST request.

2. As the age parameter is using stripslashes function, it is good to inject legitimate value and then closing it appropriately.

3. In this case, one must not concentrate on exploiting the search_user parameter rather hit on the age parameter. As it is POST request, it is easy to play with proxy to set up the value for the age parameter.

4. In general, when anyone run the successful query with the legitimate username such as root, another information such as age will be thrown on the HTML page. This clearly indicates the fact that query is consuming some another parameter too.

5. So the payloads such as age=';-- produces an error as follows

"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';--')' at line 1"

This means the application is vulnerable to POST based SQL injection and appropriate query is required to exploit it successfully.

6. One can try for fuzzing it with different requests such as Union SQL Poisoning tricks. For example: age=27') union select 1,2,3,4,5,6,7,password from user_table -- -

For any POST based SQL injection, always try to verify the fact which field is required to be attacked and whether a new parameter can be injected or not.

You may encounter this type of scenario in hacking challenges. :)

This solution is an outcome of collaborative work with Rohit (Rb1337). Hope to share some more thoughts on SQL injections.

Friday, August 05, 2011

Anatomy of OpenSSL and Penetration Testing - Breaking Benjamin

SSL is one of the most attractive and shocking protocol in myriad of ways. There is always something different about this protocol. Considering the real time security testing, you might encounter tricky scenarios while handling sessions with the SSL. OpenSSL is widely used to deploy the SSL as a open source platform. Apache configured with mod_ssl is used heavily for this purposes. During open research and technical verification, we (me and my friends) came across a domain ( having bad SSL implementation. So I thought to write a detailed post on this issue. The aim of this post is to understand the unexpected variance in the responses of the remote server when SSL connection is initiated using different OpenSSL versions

Target check : [ For educational purposes only].

A simple host discovery gives the following information which suggests that DNS load balancer is in place. Since it is a heavy eCommerce website, one must expect this.

root@bt:~# host has address has address mail is handled by 10 mail is handled by 10 mail is handled by 10

root@bt:~# host is an alias for is an alias for has address has address

This website is accessible over HTTP and HTTPS, this gives a straight forward information regarding the open ports 80/443. One can expect redirection parameters defined on server side to automatically redirect the incoming HTTP requests to HTTPS.
Further, when a simple GET request is issued to the server, it responds back with the following HTTP responses

(Status-Line) HTTP/1.0 200 OK
Server Apache-Coyote/1.1
Content-Encoding gzip
Content-Type text/html;charset=UTF-8
Content-Length 9986
Vary Accept-Encoding
Expires Fri, 05 Aug 2011 18:08:39 GMT
Cache-Control max-age=0, no-cache, no-store
Pragma no-cache
Date Fri, 05 Aug 2011 18:08:39 GMT
Connection keep-alive
Set-Cookie ebay=%5Esbf%3D%23%5E;; Path=/
Set-Cookie dp1=bu1p/QEBfX0BAX19AQA**501d6527^spref/20351fe98a7^;; Expires=Sun, 04-Aug-2013 18:08:39 GMT; Path=/
Set-Cookie cssg=9b21f5741310a02652e39d83ffdf018c;; Path=/
Set-Cookie s=CgAD4ACBOPYMnOWIyMWY1NzQxMzEwYTAyNjUyZTM5ZDgzZmZkZjAxOGPrM83K;;Path=/; HttpOnly
Set-Cookie nonsession=CgADKACBXojMnOWIyMWY1NzQxMzEwYTAyNjUyZTM5ZDgzZmZkZjAxOGYAywABTjw4rzGpIP/j;; Expires=Sat, 04-Aug-2012 18:08:39 GMT; Path=/

The Server header points to the Apache-Coyote/1.1 which may be running this flavor of Apache. Usually, it is true in number of cases.

The first three tests are conducted using OpenSSL, cURL and SSLScan in general. This host is a backtrack machine with an OpenSSL 0.9.8k 25. In this , the aim is to verify the presence of SSLv2

root@bt:~# openssl version / OpenSSL 0.9.8k 25 Mar 2009

root@bt:~# curl --version
curl 7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/ libidn/1.15
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

Test 1: Using OpenSSL, following response is detected which shows the acceptance of SSLv2.
root@bt:~# openssl s_client -connect -ssl2
subject=/C=US/O=Akamai Technologies, Inc./
issuer=/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
No client certificate CA names sent
Ciphers common between both SSL endpoints:
SSL handshake has read 995 bytes and written 236 bytes
New, SSLv2, Cipher is DES-CBC3-MD5
Server public key is 1024 bit
Secure Renegotiation IS NOT supported

Compression: NONE
Expansion: NONE
Protocol : SSLv2
Cipher : DES-CBC3-MD5

Session-ID: E03D2C3CCD43347B13383DA55F2FD326
Master-Key: 16011C613D2E862A91FD0A069AF1FFAE5058F0BFEADB87F0
Key-Arg : A9D372330CD89517
Start Time: 1312569173
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)

Test 2: Using cURL to verify the state.
root@bt:~# curl -v -2 -k
* About to connect() to port 443 (#0)
* Trying connected
* Connected to ( port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv2, Client hello (1):
* SSLv2, Server hello (4):
* SSLv2, Client key (2):
* SSLv2, Client finished (3):
* SSLv2, Server verify (5):
* SSLv2, Server finished (6):
* SSL connection using DES-CBC3-MD5

* Server certificate:
* subject: C=US; O=Akamai Technologies, Inc.;
* start date: 2010-10-06 16:41:56 GMT
* expire date: 2011-10-06 16:40:47 GMT

Test 3: Using SSLScan to verify the state.
root@bt:~# sslscan
Version 1.8.2
Testing SSL server on port 443

Supported Server Cipher(s):
Accepted SSLv2 168 bits DES-CBC3-MD5
Accepted SSLv2 56 bits DES-CBC-MD5
Accepted SSLv2 40 bits EXP-RC2-CBC-MD5
Accepted SSLv2 128 bits RC2-CBC-MD5
Accepted SSLv2 40 bits EXP-RC4-MD5
Accepted SSLv2 128 bits RC4-MD5

It has been verified that this particular domain is accepting SSLv2 and all the testing output has confirmed this. Note , in this OpenSSL version 0.9.8k is used.

Now moving on to second set of tests with same tools having updated version of OpenSSL as follows

user@ubuntu:~$ openssl version / OpenSSL 0.9.8o 01 Jun 2010

curl 7.21.3 (i686-pc-linux-gnu) libcurl/7.21.3 OpenSSL/0.9.8o zlib/ libidn/1.18
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smtp smtps telnet tftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

The versions are different. In order to conduct security testing of SSL, the same tests are conducted again.

Test 4: Verifying the SSLv2 (updated OpenSSL)
user@ubuntu:~$ openssl s_client -connect -ssl2
2543:error:140A90C4:SSL routines:SSL_CTX_new:null ssl method passed:ssl_lib.c:1453:

The connection over SSLv2 fails. Let's move on to next case

Test 5: Verifying the SSLv2 (updated cURL)
user@ubuntu:~$ curl -s -v -k -2
* About to connect() to port 443 (#0)
* Trying connected
* Connected to ( port 443 (#0)
* SSL: couldn't create a context!
* Closing connection #0

cURL also fails for the SSLv2. Jumping on to next and final test

Test 6: Verifying the SSLv2 (SSLScan)
user@ubuntu:~$ sslscan
Version 1.8.2

ERROR: Could not create CTX object.

Testing SSL server on port 443

Supported Server Cipher(s):
Rejected SSLv3 256 bits ADH-AES256-SHA
Rejected SSLv3 256 bits DHE-RSA-AES256-SHA
Rejected SSLv3 256 bits DHE-DSS-AES256-SHA
Accepted SSLv3 256 bits AES256-SHA
Rejected SSLv3 128 bits ADH-AES128-SHA
Rejected SSLv3 128 bits DHE-RSA-AES128-SHA
Rejected SSLv3 128 bits DHE-DSS-AES128-SHA

In this test, no SSLv2 output (rejected/accepted) is there. However, one can see that "ERROR: Could not create CTX object" notification which primarily is an outcome of the fact that SSLScan fails to instantiate context for SSLv2.

As it is known in the wild that all the newer version of browser hardly initiate connection using SSLv2. It looks like OpenSSL 0.9.8o 01 is doing the same way. Hardening the client straight away so that only updated version of protocol are used to do that.

Note: for penetration testing, my personal advise is to use OpenSSL 0.9.8k 01 or any version less than <= k for strong testing. It is also a good choice to use <=k versions and also > k versions to differentiate the output.

Giving a final check on the certificates (, it has been noticed that certificate is already expired

and the amazing result is also presented below

So overall, this situation is really bad for an eCommerce website. For verification tests of SSL one should not rely on single tool. It is preferable to use OpenSSL, cURL and SSLScan as an overall tool set and the protocol should be fuzzed appropriately. Be sure of the OpenSSL version you are using.

NOTE: Additionally, declarative security can also be used to prevent MITM attacks. I will be releasing Mozilla Firefox addon soon (under review). This addon is capable of detecting Strict-Transport-Security parameter in HTTP response header and notify the penetration tester about the usage of declarative security (whether the server wants to harness the browser protection)

Stay tuned. Enjoy !

Monday, August 01, 2011

Framebusting - The Dual Protection Core

Since the outcome of ClickJacking attacks, framebusting has become the unavoidable part of web application security. Considering the real world scenario, it has been noticed that still the appropriate protections have not been placed in the plethora of websites. Seclab guys conducted the study on framebusting. They raise a point on the right way of implementing the framebusting code. However, a similar protection features have been implemented in the famous websites such as Twitter, Facebook etc. However, my personal opinion is to use the dual protection which includes the implementation of declarative security as well as framebusting code. No doubt, only new versions of certain browsers such as Internet Explorer, Firefox etc support some of the declarative security features. Deploying declarative security feature is a good additional point. I have written Firefox addons that detect the presence of declarative security headers that are coming from servers. In this post, I am using X-Frame-Options detector hosted here

Lets see how the twitter implements the framebusting code

========================= TWITTER ======================================
function bust () {
document.write = ""; = window.self.location;
setTimeout(function() {
document.body.innerHTML = '';
}, 0);
window.self.onload = function(evt) {
document.body.innerHTML = '';
if ( !== window.self) { // are you trying to put self in an iframe?
try {
if ( { // this is illegal to access unless you share a non-spoofable document domain
// fun times
} else {
bust(); // chrome executes this
} catch (ex) {
bust(); // everyone executes this

========================= TWITTER =====================================

This works very well. The beauty of this protection is even if the webpage is framed using advanced techniques, the twitter displays the white page thereby dethroning the success rate of successfully framed web page. Give a shot yourself. Apart from this, twitter also throws X-Frame-Options header which adds another protection layer to use the inbuilt browser protection mechanism

Let's have a look at the Facebook

========================= FACEBOOK ==============================

function si_cj(m)
new Image().src="http:\/\/\/common\/scribe_endpoint.php?c=si_clickjacking&t=8340"+"&m="+m;
{throw 1;}var si_cj_d=["","\/pages\/",""];

var href=top.location.href.toLowerCase();

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

{if (href.indexOf(si_cj_d[i])>=0){throw 1;}}si_cj("3 ");}

catch(e){si_cj("1 \t");window.document.write("\u003cstyle>body * {display:none !important;}\u003c\/style>\u003ca href=\"#\" onclick=\"top.location.href=window.location.href\" style=\"display:block !
important;padding:10px\">\u003ci class=\"img sp_8lnh2w sx_fcd3c0\" style=\"display:block !important\">\u003c\/i>Go to\u003c\/a>");

============================ FACEBOOK ==============================

This code works appropriately and displays the small Facebook image with a link to main Facebook page in the Iframe as presented below

Facebook does not use declarative security protection feature

Google implements the code as follows

if (top.location != self.location) {top.location = self.location.href;}

It also implements the X-Frames-Options header to add another layer.

The cases discussed above are from the most explored websites. However, the normal scenarios are very bad. My suggestion is to implement both solutions collaboratively rather than sticking to one. The browser security guys are implementing inbuilt solutions and we should harness the power. The dual protection is always good.

Thursday, July 28, 2011

InfoJacking - A Walk through Social Networking Websites

Last month, I presented at Source Seattle conference. The slides are available for download from Cigital's website here. I also wrote some views about different cases of collecting information here. The detection of hidden devices such as WAF's , protection against advanced attacks are very much important. I discussed different cases in my presentation about collecting information from HTTP response headers. I thought to just move on and verify the state of some social networking websites.

The Facebook response header dump looks like as follows

(Status-Line) HTTP/1.1 200 OK
Cache-Control private, no-cache, no-store, must-revalidate
Expires Sat, 01 Jan 2000 00:00:00 GMT
P3P CP="Facebook does not have a P3P policy. Learn why here:"
Pragma no-cache
Set-Cookie; path=/;
Set-Cookie wd=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/;; httponly
Content-Encoding gzip
Content-Type text/html; charset=utf-8
X-Cnection close
Transfer-Encoding chunked
Date Fri, 29 Jul 2011 02:39:59 GMT

The highlighted part in the dump suggests that Facebook is running under the shadow of NetScaler [WAF + Load Balancer] device. On continuous observing and validating certain functions, I extracted some combinations of URL's and related HTTP header sent with it i.e. X-FB-Server

The X-FB-Server header value was changing with different responses. However, one thing remains same is the combination of X-FB-Server with X-Cnection. This simply projects that WAF + Load Balancer is playing a role.

However, Facebook does not reveal the web server information in Server header. Additionally, Facebook responses contain the "X-Backend :" header with different values. For informational purposes, the X-Backend header is sent by 3 different servers : nginx , Apache-Coyote and lighttpd primarily.

The point is HTTP response headers reveals a lot of information which can be potentially useful for testing purposes.