XML Indenter

With the release of the 0.7.7 we’ve bundled a new Python action particularly useful when dealing with unformatted XML.

The following is an excerpt of an embedded XML file taken from a malicious PDF document.

XML Indenter

Focusing on security, this beautifier does not try to validate the content of the document, having also the advantage of being faster than other tree-based indenters.
As a side note, this plugin is compatible with any SMGL-based such as HTML and XHTML.

MicroType Express

MicroType Express is the (optional) compression technology used by Embedded OpenType fonts. It was specifically designed to compress TrueType fonts. These fonts are generally to be found in web pages or Office documents.

Internet Explorer with EOT fonts

In this screenshot we have Internet Explorer displaying fonts download from remote. It is very easy to embed fonts in a web page.

@font-face {
    font-family: Piefont;
    font-style:  normal;
    font-weight: normal;
    src: url(PIE0.eot);
  }
@font-face {
    font-family: GS;
    font-style:  normal;
    font-weight: normal;
    src: url(GOUDYST2.eot);
  }
  @font-face {
    font-family: Garabold;
    font-style:  normal;
    font-weight: 700;
    src: url(GARAMON5.eot);
  }
  @font-face {
    font-family: Garanorm;
    font-style:  normal;
    font-weight: normal;
    src: url(GARAMON4.eot);
  }
  @font-face {
    font-family: Script;
    font-style:  normal;
    font-weight: normal;
    src: url(SCRIPTM2.eot);
  }

What happens when Internet Explorer tries to open EOT fonts is that it loads T2Embed.dll from the System32 directory.

T2Embed DLL

The job of this DLL is to convert EOT fonts back to the original OpenType format which is then parsed and displayed. Thus, EOT fonts are subject to exploits either in their MicroType Express layer or in the resulting OpenType font. In fact, lzcomp, the custom compression algorithm based on lz77 used by MicroType Express, has been exploited as a vector for remote code execution. It should be noted that the vulnerability has been reported in 2010 and the W3 submission by Microsoft of the MicroType Express standard is dated 2008. The lzcomp decompression code contained in the W3 submission does not include the patches introduced after the vulnerability was reported (I checked). So while probably few will use the code anyway, they should be careful to add safety checks in order to not include the above mentioned vulnerability in their own code.

While already with version 0.7.6 the Profiler had support for uncompressed Embedded OpenType fonts, only with the upcoming 0.7.7 version a partial support for MicroType Express has been added. I say partial because, although the embedded OpenType font gets completely decompressed, only the glyf and loca tables out of those which are deconstructed are rebuilded in order to allow the disassembling of bytecode. Tables which are not yet rebuilded are: cvt, hdmx and VDMX. The use of the T2Embed.dll for conversion was not an option, since it doesn’t fit with the Profiler safety standards.

Word doc with fonts

This is a Word Document containing Embedded OpenType fonts.:)

Compact Font Format, Type2 and OpenType

The Compact Font Format (CFont) was developed by Adobe and it is a container for one or more fonts. Although not compressed, it’s a format designed to save space as the name suggests.

Compact Font Format

The bytecode contained in CFonts is either Type1 or Type2, both very similar and supported by the Profiler, although nothing prevents from storing another type of bytecode.

OpenType

The support of this font format also improves the support for OpenType fonts, because these fonts can store glyph outlines in a CFF table, rather than in a glyf table such as TrueType fonts. CFF tables contain Compact Fonts.

PDF Fonts

In this last screenshot we can see an example of font detection inside of a PDF.

Adobe Type1 fonts

This font format is very common and mainly found in PDFs. It was used as a vector for native code exeuction in the iOS 4.3 jailbreak. To trigger the vulnerability it was sufficient to open a PDF inside Safari.

T1 jailbreak

In the screenshot we can see the disassembled code and more precisely the first line of the exploit (a call with a negative number of arguments). As I wrote in this paper and discussed at DeepSec 2011, there are some interesting parts in the Adobe specification of the format. One part explains the reason for Type1 fonts to contain bytecode.

Since Type 1 fonts are expressed as computer programs, they are copyrightable as is any other computer software. For some time, the copyright status of some types of typeface software was unclear, since typeface designs are not copyrightable in the United States. Because Type 1 fonts are computer programs rather than mere data depicting a typeface, they are clearly copyrightable. A copyright on a Type 1 font program confers the same protection against unauthorized copying that other copyrightable works, including computer software, enjoy.

This is important, not only because it tells a great deal about priorities during development (copyright vs security), but also because Type1 is one of the oldest font formats and as such it sets a trend. In fact, the price of the license granted by Adobe to implement such fonts was so high that in 1991 Apple created their own font type (TrueType).

The other part of the specification says something about the security of the parser.

Because Type 1 font programs were originally produced and were carefully checked only within Adobe Systems, Type 1 BuildChar was designed with the expectation that only error-free Type 1 font programs would be presented to it. Consequently, Type 1 BuildChar does not protect itself against data inconsistencies and other problems.

Web Open Font Format and Embedded OpenType fonts

In the upcoming 0.7.6 release of the Profiler a great effort has been invested into supporting font formats. After SFonts (TrueType and collections) released with 0.7.5, the first font formats I’m going to present are WOFFs and EOTs. Both this font formats are actually containers for SFonts and they are used to deploy fonts on the web and are therefore usually compressed.

The Web Open Font Format (WOFF) is quite easy as format and certainly the more secure and logical of the two.

WOFF

Being containers for SFonts, the Profiler contains a converter to SFont, which gives the ability to analyze the compressed font.

Same applies to Embedded OpenType fonts which is a format created by Microsoft.

EOT

These fonts are not only deployed on the web but can be found in Office documents as well. Unfortunately the Profiler doesn’t yet support compressed Embedded OpenType fonts. The compression happens in stages and uses a custom compression algorithm created by Microsoft and based on lz77 called lzcomp. This algorithm has been used as an exploit vector for remote code execution.

TrueType & TrueType Collection Fonts

We’re happy to announce that the new 0.7.5 version of the Profiler offers support for TrueType (SFNT) fonts. This is the first step in the direction of giving our users a complete solution for font formats and analyze them inside documents. The recent threat landscape has seen the rise of fonts as an infection vector. Two notable examples are Duqu and the iOS 4.3 jailbreak.

TrueType

In the screenshot above we see several TrueType fonts being analyzed inside of a PDF document.

One of the offered features is the capability to output the code contained in a TrueType font. While this feature can’t be used to establish the risk factor of a font at glance, it is useful to security analysts.

TrueType code

Functions are associated with their glyph name, in order to more easily establish which instructions are associated to a particular character.

The report also shows the metadata, which doesn’t offer any kind of security assurance, but might be of interest to the user.

TrueType metadata

As with every file type supported by the Profiler it is possible to inspect the format of TrueType and TrueType Collections fonts as well.

TTC format

The screenshot above shows the format of a TrueType collection. Collections host more than one font and every one of them can be analyzed.

It should be noted that TrueType fonts are hosted in a format called SFont. SFonts can also host other font types. An example of this scenario are OpenType fonts by Microsoft, which can be TrueType compatible but go beyond the TrueType format. While the current support for TrueType also allows to inspect OpenType fonts, it is our intent in the near future to cover OpenType fonts in detail.

More updates related to fonts should soon be available. So, as usual, stay tuned. 🙂

Pastebin plugin

Coming with the new 0.7.4 release, the Pastebin action is a handy tool for easy sharing of text-based content with colleagues and friends.

Pastebin plugin (result)

Thanks to the new property editor, the full feature set has been implemented; amongst the usual options like syntax highlight, title and content, the user will also be able to change the visibility preference and decide for how long the content should be available online.

Pastebin plugin (settings)

A security confirmation check has also been added to avoid unintentional disclosure of information. 🙂

PDF object search

The soon to be released version 0.7.4 of the Profiler features a useful PDF object search functionality. The introduction of this feature was possible thanks to the newly introduced parameters API and format specific actions.

PDF search action

Through this action it’s possible to perform predefined searches as for object with streams, JavaScript or embedded files.

PDF JavaScript search

But it’s also possible to perform custom dictionary searches.

PDF dictionary search

Matches can be tagged and highlighted. Also new searches can be performed without resetting previous matches. In fact, in the screenshot below we can observe two different type of matches.

PDF search matches

This was a requested feature and it certainly is very useful when analyzing PDFs. Stay tuned as more important news will be soon announced. 🙂

Parameters & Settings

In the upcoming release of the Profiler (0.7.4) actions and scripts have a way to ask the user for parameters and settings: a new set of APIs featuring a property editor dialog.

Properties

Here’s the complete code of the sample followed by explanations.

import ProUI

xml = """


  <section label="General">
    <property id="0" label="Name" type="edit" value="object" />
    <property id="1" label="Size" type="static" value="(0,0)">
        <property id="2" label="Width" type="integer" value="0" signed="false" radix="10" align="0" maxbits="16" />
        <property id="3" label="Height" type="integer" value="0" signed="false" radix="10" align="0" maxbits="16" />
    </property>
  </section>
  
  <section label="Options">
    <property id="4" label="Word wrap" type="check" value="false" />
    <property id="5" label="Syntax" type="combo" value="1">
      <list>
        <i>JavaScript</i>
        <i>C++</i>
        <i>Pascal</i>
      </list>
    </property>
  </section>
  
  <section label="Files">
    <property id="6" label="Open file" type="open-file" value="C:\\test.txt" />
    <property id="7" label="Save file" type="save-file" value="C:\\test2.txt" />
    <property id="8" label="Select directory" type="open-directory" value="C:\\temp" />
  </section>
  
  <section label="Content">
    <property id="9" label="Text" type="text">
        This \tis a\nsample text
    </property>
  </section>
  
  <section id="20" label="Numbers">
    <property id="10" label="Base address" type="integer" value="401000" signed="false" radix="16" align="8" />
    <property id="11" label="Char" type="integer" value="127" signed="true" radix="10" align="0" maxbits="8" />
  </section>
  
"""

def UpdateSize(pe):
    sz = "(" + str(pe.getValue(2)) + "," + str(pe.getValue(3)) + ")"
    pe.setValue(1, sz)

def ParamsCallback(pe, id, userdata):
    print("changed: " + str(id) + " value: " + str(pe.getValue(id)))
    if id == ProUI.ProPropertyEditor.Init:
        UpdateSize(pe)
    elif id == 2 or id == 3:
        UpdateSize(pe)
        pe.setValue(0, "test2")
        pe.setValue(5, 2)
        pe.setValue(10, 0x2000)
    elif id == 4:
        b = pe.isVisible(20) == False
        pe.setVisible(20, b)
        if b == False:
            pe.setErrors([6, 7])
        else:
            pe.clearErrors()
    return True

def TestAction():
    context = ProUI.getContext()
    params = context.askParams(xml, "Test", ParamsCallback, None)
    print(params)
    return 0

Let’s start with the action code.

def TestAction():
    context = ProUI.getContext()
    params = context.askParams(xml, "Test", ParamsCallback, None)
    print(params)
    return 0

This code shows a property editor dialog specifying an XML string to create the dialog, a settings key (optional) and a callback (optional). The return value is a dictionary with the values of the properties with their id as key or None when the dialog is rejected.

{0: 'test', 1: '(4,0)', 2: 4, 3: 0, 4: False, 5: 1, 6: 'C:\\test.txt', 7: 'C:\\test2.txt', 8: 'C:\\temp', 9: 'This \tis a\nsample text', 10: 8192, 11: 127}

I’ll talk later about what the settings key means. Let’s first understand the XML syntax.

The XML root tells the function to create a property editor with the (optional) title “Settings”.

<section label="General">

A section is created. Properties do not need a section as parent, but it might be visually more appealing to specify one. Child nodes of sections are properties. Properties can have other properties as child nodes, but not sections.

<property id="0" label="Name" type="edit" value="object" />

The first property being created is a single line edit field with the id of 0 and a value of “object”. id and type attributes are mandatory for properties. Sections may optionally specify an id as we’ll see later.

    <property id="1" label="Size" type="static" value="(0,0)">
        <property id="2" label="Width" type="integer" value="0" signed="false" radix="10" align="0" maxbits="16" />
        <property id="3" label="Height" type="integer" value="0" signed="false" radix="10" align="0" maxbits="16" />
    </property>

Here we have one static property with two integer child properties. A static property is a non-editable text which can only be set programmatically.

An integer property can specify various things, although the only mandatory attributes remain id and type. Most of the attributes are self-explanatory. align specifies the 0s which may prefix the number to obtain the desired alignment. For example, the number 1 with an alignment of 4 will be displayed as 0001. maxbits specifies the maximum number of bits the integer can measure (at the time it defaults to 10000).

  <section label="Options">
    <property id="4" label="Word wrap" type="check" value="false" />

Inside a new section a check property is specified.

    <property id="5" label="Syntax" type="combo" value="1">
      <list>
        <i>JavaScript</i>
        <i>C++</i>
        <i>Pascal</i>
      </list>
    </property>

Following there’s a combo property. The list of the combo is specified as the child node list and the default index is specified as the value attribute.

  <section label="Files">
    <property id="6" label="Open file" type="open-file" value="C:\test.txt" />
    <property id="7" label="Save file" type="save-file" value="C:\test2.txt" />
    <property id="8" label="Select directory" type="open-directory" value="C:\temp" />
  </section>

These three properties are related to file operations. When the user activates one, he will be able to open a file dialog to perform the requested operation.

  <section label="Content">
    <property id="9" label="Text" type="text">
        This \tis a\nsample text
    </property>
  </section>

The text property specifies a multi-line text field. When the user activates this property, a multi-line text input dialog is displayed in order to change the value.

  <section id="20" label="Numbers">
    <property id="10" label="Base address" type="integer" value="401000" signed="false" radix="16" align="8" />
    <property id="11" label="Char" type="integer" value="127" signed="true" radix="10" align="0" maxbits="8" />
  </section>

The properties in this section are not any different than those seen before, but it should be noted that in this case the section has an id attribute. Giving an id to a section makes it possible to set the visibility or the enabled/disabled state of the section and its children.

Let’s analyze the callback.

def UpdateSize(pe):
    sz = "(" + str(pe.getValue(2)) + "," + str(pe.getValue(3)) + ")"
    pe.setValue(1, sz)

def ParamsCallback(pe, id, userdata):
    print("changed: " + str(id) + " value: " + str(pe.getValue(id)))
    if id == ProUI.ProPropertyEditor.Init:
        UpdateSize(pe)
    elif id == 2 or id == 3:
        UpdateSize(pe)
        pe.setValue(0, "test2")
        pe.setValue(5, 2)
        pe.setValue(10, 0x2000)
    elif id == 4:
        b = pe.isVisible(20) == False
        pe.setVisible(20, b)
        if b == False:
            pe.setErrors([6, 7])
        else:
            pe.clearErrors()
    return True

ParamsCallback has three arguments. pe is the ProPropertyEditor class instance. id is the property being modified or the notification code (Init, Accept). userdata is the custom data specified in the askParams method, which in this case is None.

The UpdateSize function updates the value of the static property when one of its children has been changed. Other fields are changed for the purpose of demonstration.

        pe.setVisible(20, b)

This line sets the visibility of the last section.

        if b == False:
            pe.setErrors([6, 7])
        else:
            pe.clearErrors()

The setErrors method allows to highlight properties in red. The idea is that a callback might perform some checks when being notified with the ProPropertyEditor.Accept code, highlight properties which are not accepted and return False to ask the user to enter correct values. Calling clearErrors or setErrors with an empty list will achieve the same result.

Here’s a screenshot with two highlighted properties and the last section hidden.

Properties 2

Let’s go back to askParams method. I haven’t yet explained the settings key (“Test”). This is an optional argument: it specifies if and where the values of the properties should be stored in case the dialog is accepted. The specified key name should be similar or equal to the name of the action to avoid conflicts. If the property dialog changes and the old settings must be discarded, it can be achieved by specifying a version at the end of the key name: “Test#1”. When the version number is omitted, it defaults to 0.

It should be noted that static and multi-line text properties are not saved automatically. The latter to avoid too large values being stored. However, it is still possible to save and restore these values through the Init and Accept notification codes by using the settings API.

# restore
ProUI.ProSettings.getValue("Test/mytext")
# save
ProUI.ProSettings.setValue("Test/mytext", text)

Key names starting with “_” are reserved and shouldn’t be used.

Finally, let’s see how actions can now optionally specify a configuration function.

Configure action

[TestAction]
label = Test
file = testfile.py
context = any
config = TestConfig

config specifies the name of a function to be called inside of file.

This new set of APIs opens the door to many interesting customizations for actions, scripts and other components, and we will soon show you some of them. 🙂

Python 3 SDK: actions & custom scripts

The new version 0.7.3 of Cerbero Suite features a powerful Python 3 SDK, which enables to run custom scripts and actions. Let’s first take a look at a simple script. Just press Ctrl+R (or “Execute action…” in the context menu of a view) and go to “Custom”:

Simple script

As it is easy to guess, this basic script shows a message box. Message boxes can be used to notify things to the user or to ask him a question. Most of the time they won’t be necessary and the standard output can be used instead. All the output produced by Python will be visible in the output console. In fact, the console will become visible when something is printed to it (this behavior can be changed from the options).

Output console

The SDK can be used to retrieve data from views, set their data, create new views and so on. But before looking at a more advanced script, let’s talk about a new feature of Cerbero Suite: actions. For the purpose of demonstration let’s take a malware with obfuscated JavaScript.

Obfuscated JS

And now let’s again press Ctrl+R in the context of the obfuscated JavaScript.

Actions

By activating the “Beautify JavaScript” action we will get a beautified version (jsbeautifier.org) of the previously obfuscated JavaScript.

Beautified JS

Python actions are defined in the config/actions.cfg file.

[JSBeautify]
category = JavaScript
label = Beautify JavaScript
file = javascript.py
context = text

The section name (JSBeautify) specifies the id of the action and is also the name of the function to be called in file. The file field supports absolute paths as well, otherwise the script will be loaded from plugins/python. The category and label specify in which category inside the execute action dialog the action should be grouped and its description. When the category field is omitted, it will default to “Other”.

The context field is very important as it specifies when the action should be available for use. In this specific case, the action can be used in any text view. An action can also be available in more than one context.

; available both in text and hex views
context = text|hex

; available in text and hex views only when text or data is selected
context = text|hex|sel

; always available even when not in a view
context = any

Now let’s see how to create an action which decodes some selected text from base64 and shows the decoded bytes in a new hex view. First it is necessary to define the action.

[Base64Decode]
category = Samples
label = Base64 decoder
file = samples.py
context = text|sel

And here’s the Python code.

from Pro.UI import *

def Base64Decode():
    context = proContext()
    view = context.getCurrentView()
    if view.isValid() and view.hasSelection():
        text = view.getSelectedText()
        decview = context.createView(ProView.Type_Hex, "Base64 decoded data")
        import base64
        decview.setBytes(base64.b64decode(text.encode("utf-8")))
        context.addView(decview)
    return 0

Let’s see it in action with a PGP public key.

PGP Public Key

And the decoded data.

PGP decoded key

Although the SDK is brand new, you will see very soon some new useful actions implemented. 🙂