Grey bar Blue bar
Share this:

Fri, 11 Nov 2011

Decrypting iPhone Apps

This blog post steps through how to convert encrypted iPhone application bundles into plaintext application bundles that are easier to analyse.

Requirements: 1) Jailbroken iPhone with OpenSSH, gdb plus other utilities (com.ericasadun.utilities etc. etc.) 2) An iPhone app 3) On your machine:

  • otool (comes with iPhone SDK)
  • Hex editor (0xED, HexWorkshop etc.)
  • Ida - Version 5.2 through 5.6 supports remote debugging of iPhone applications (iphone_server).
For this article, I will use the app name as “blah”.

Some groundwork, taken from Apple's API docs [1, 2]:

The iPhone apps are based on Mach-O (Mach Object) file format. The image below illustrates the file format at high-level:

A Mach-O file contains three major regions: 1. At the beginning of every Mach-O file is a header structure that identifies the file as a Mach-O file. The header also contains other basic file type information, indicates the target architecture, and contains flags specifying options that affect the interpretation of the rest of the file. 2. Directly following the header are a series of variable-size load commands that specify the layout and linkage characteristics of the file. Among other information, the load commands can specify:
  • The initial layout of the file in virtual memory
  • The location of the symbol table (used for dynamic linking)
  • The initial execution state of the main thread of the program
  • The names of shared libraries that contain definitions for the main executable's imported symbols
3. Following the load commands, all Mach-O files contain the data of one or more segments. Each segment contains zero or more sections. Each section of a segment contains code or data of some particular type. Each segment defines a region of virtual memory that the dynamic linker maps into the address space of the process. The exact number and layout of segments and sections is specified by the load commands and the file type. 4. In user-level fully linked Mach-O files, the last segment is the link edit segment. This segment contains the tables of link edit information, such as the symbol table, string table, and so forth, used by the dynamic loader to link an executable file or Mach-O bundle to its dependent libraries.

The iPhone apps are normally encrypted and are decrypted by the iPhone loader at run time. One of the load commands is responsible for decrypting the executable.

Push EBP
Mov EBP, ESP
JMP loc_6969
loc_6969:
Once you have downloaded and installed an app on your iPhone, make a copy of the actual executable on your machine.

Note1: The blah.app is not the actual executable. If you browse this folder, you will find a binary file named blah. This is the actual application binary.

Note2: To find the path where your application is installed, ssh onto your iPhone and use the following command:

sudo find / | grep blap.app
Once you have copied the app binary on your machine, follow the steps below (on your local machine).

Open up a terminal and type the following command:

otool —l blah | grep crypt
This assumes that iPhone SDK or otool is already installed on your machine.

The above command will produce the following output:

If cryptid is set to 1, it implies that the app is encrypted. cryptoff and cryptsize indicates the offset and size of crypt section respectively. Now, firstly we'll have to locate the cryptid in the binary and set it to zero. This is done so that when we finally decrypt the binary and execute it on iPhone, the loader does not attempt to decrypt it again. Open the binary in a hex editor and load the binary. I did not come across any definite method of locating the cryptid. Once you have loaded the binary in a hex editor, search for “/System/Library/Frameworks”. You should be able to locate it around the address 0x1000. In the line, just above the very first instance of this statement (/System/Library/Frameworks), you will find bytes 01. Flip it to 00 and save the file.

Note3: In case you find multiple instances of 01, use coin-tossing method of choosing between them.

Use otool again to query the crypt data. You will see that the cryptid is now set to 0 (zero).

Next, we need to run the app, which was installed on iPhone and take a memory dump.

Note4: The actual application code starts at 0x2000. The cryptsize in case of our sample app is 942080 (0xE6000). Hence, we add 0x2000 and 0xE6000.

0x2000 + 0xE6000 = 0xE8000
Therefore, we need to dump the running process from 0x2000 till 0xE8000. Now, ssh onto your iPhone, run the target app and look for the process id using “ps —ax” command. Once you have the process id, use the following command to dump the process:
gdb —p PID
dump memory blah.bin 0x2000 0xE8000
Once you have taken the memory dump, use “quit” command to exit gdb. Use the following command to get the size of memory dump:
ls —l blah.bin
The size of this bin file should exactly be same as the cryptsize of the original app. Refer to screenshot above. Now pull this bin file onto your local machine. On your local machine, load the bin file in a hex editor and copy everything (using select all or whatever). Close the file and open the original app in the hex editor. (The file in which we modified cryptid 01 to 00). If you remember, the cryptoff was 4096, which is 0x1000 (in hex). Proceed to memory address 0x1000 and make sure that your hex editor is in overwrite mode, not in append mode. Once you are on memory address 0x1000, paste everything you copied from the bin file. This will overwrite the encrypted section with the decrypted one. Save the file and you're done.

Open the file in IDA pro and you'll see the difference between the encrypted and decrypted binaries. At this point, you can easily reverse engineer the app and patch it. The first image below shows an encrypted app and the second one illustrates a decrypted app:

After patching the application, ssh onto the iPhone and upload it to the application directory. This would mean replace the original binary with the patched one. Once uploaded, install a utility called "ldid" on your iphone.

apt-get install ldid
Finally, sign the patched binary using ldid:
ldid -s blah
This will fix the code signatures and you will be able to run the patched app on your iPhone.

References:

1) http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html

2) http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/otool.1.html

Wed, 27 Oct 2010

Analysis of a UDP worm

Introduction

From time to time I like to delve into malware analysis as a pastime and post interesting examples, and recently we received a malware sample that had a low-detection rate. Anti-Virus coverage was 15/43 (35.7%) based on a virustotal.com report and Norman sandbox did not detect any suspicious activity as shown in the report below:

norman sandbox report

Norman sandbox report did not show any registry or network activity. This might be due to the use of virtual CPU or sandbox bypass techniques by the malware. Sunbelt sandbox was down at the time of the analysis.

Dynamic analysis indicated that the malware copies itself to the "application data" directory of the current logged-on user and achieves automatic startup by adding the following registry entry:

  • key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Taskman
  • Value: %AppData%\ygmdrm.exe
It then starts communicating via UDP with the following C&C servers on port number 14000:
  • jebena.ananikolic.su
  • peer.pickeklosarsk.ru
  • teske.pornicarke.com
  • juice.losmibracala.org
  • 92.241.190.237
The UDP traffic was scrambled and had the following sequence:

Code analysis of the malware resulted in the following findings:

Virtual CPU bypass

Anti-virus programs achieve heuristic detection of unknown malware code by parsing the binary code inside a virtual CPU to detect suspicious pattern (packers, encryptors, etc) and OS activities. Most modern AVs are able to detect and skip "code traps" designed to evade detection, such as time delays, intentional loops and unsupported CPU instructions. However, based on the AV coverage report this malware was able to evade huristic detection in a number of AV products by causing indirect execution delays through crafted calls to GDI functions as shown in the following API call log:

Code injection

The actual malware code is launched after evasive GDI calls. A page of memory is allocated using VirtualAlloc API, 1760 bytes are copied to the newly allocated area and the control is passed to this code with the "call eax" insturction as shown in the following code anippet:
The second stage searches for explorer.exe process and injects its code into it using CreateRemoteThread technique.

Network communications

The first 5 UDP packets were found to be connect request packets (starting with 0x18 command code) and sequence number exchange. The 6th packet with data size of 269 bytes seems interesting and could contain bot commands:

The decryption function was found at offset 0x58be of the second code stage :

The decryption algorithm can be presented by the following formula:

D(buff[n])=buff[n] XOR (buff[n-1]*pow(2,(n-1 AND 3)) where n values range from 1 to data_size-1.

The decrypted buffer contents are not completely readable and contain some metadata inserted at various positions. This indicates that the buffer is also compressed using a byte level compression algorithm. Further debugging reveals a decompression function at offset 0x1118 and decompressed command content is shown in the figure below:

The command instructs the bot to change the startup home page of the victim's browser to "http://www.juniormind.com/" for a possible SEO campaign.

Other features

Analysis of the text strings in the second stage code indicates that the malware has other capabilities such as:
  1. USB drive infector (via autorun.inf)
  2. Download and execute
  3. Remote Firefox cookie dump
This is cause for concern and warrants a a high risk rating, as opposed to the "low risk" in provided in ThreatExpert.com's report.

Conclusion

Apart from signatures, it's still pretty easy to write malware to bypass A/V heuristic checks, as the GDI calls in this sample showed.

Sat, 1 May 2010

Password Strength Checker & Generator

In my previous role working as a security manager for a large retailer, I developed some password tools for various purposes, primarily to help non-security people with some of the basics. I licensed them under the GPL, and I think it's about time they saw the light of day.

There are a couple of tools, which I will explain below. They're all written in JavaScript, primarily because it is cross-platform, but can be centrally hosted. They all work in Firefox and Internet Explorer, although the automatic copy to clipboard functionality of the service desk tool is IE only.

The intention is for the tools to be placed into your organisation's intranet somewhere. I found they came in much use, allowing me to reference a specific tool and setting rather than esoteric password theory in documents. For example, security standards documents would say "Service account passwords should either be generated by the password generator set to the service account setting, or be rated as "very strong" by the password strength checker", which is far more practical than quoting a list of password rules.

Being centrally hosted also allows updates to be made immediately in the case of a policy change, new common password addition, or bug. This also allowed web logs to provide an audit trail of who was using the tools. Particularly useful in the case of monitoring service desk activity e.g. If the service desk records 100 password resets, and the tool only saw 10 hits, you know something's up.

If you're a tactile learner, you can grab them here.

Password Strength Checker

This tool was written in response to the poor attempts at password strength checkers seen on many sites. They do basic checks for upper, lower-case characters and numbers. This allows passwords like "Password1" to be marked as "strong." Primarily based on Tyler Atkins' entropy and common word checker, I put together a more advanced utility. This will check the chosen password for:

  • Length (over 8 characters)
  • Character sets (lowercase, uppercase, numbers, special characters)
  • Frequency (checks for common sets of characters e.g. "u" following "q", biased to English)
  • Common Words (checks that common words aren't used e.g. Password1)
I've added a progress bar from Gerd Riesselmann, and a key for guidance. I've also eased the password strength requirements to better fit reasonable corporate password policies. These can be easily modified in the code though.

There are two versions provided, one which displays the results of the entropy calculations, and one which does not (user's rarely care).

Password Generators

There are three password generators, each with a different audience in mind.

Full Password Generator

The full password generator is the most complex and has a number of features:

  • Generate random passwords of varying complexity based on a "usage" selector such as "user", "administrator" or "service account". These match up to the complexity key in the strength checker.
  • Generate lists of passwords to be used as distributed One-Time-Password lists. This is useful if passwords are regularly required between two parties to avoid using a static password. The list can be delivered via an alternative medium than the data being transmitted, and an agreed rotation period set up, such as a new password to be used "every day" or "every week".
  • Create a NATO alphabet version of the password for speaking over the phone with the "will be spoken" option
The actual password generation code was courtesy of the no-longer-available CryptoMX tools, and the NATO alphabet conversion code was courtesy of L. Bower.

Service Desk Password Generators

The service desk password generators were created to help the service desk stop resetting everyone's password to the same thing. It's one of the most pervasive security problems in any organisation, the service desk are told to reset passwords to some common password like "abc123", "Password<x>" or "<username>". Most user's know it, and if you do ever investigate service desk password resets, will find some serious abuses going on. This tool is a quick and dirty way to provide more reasonable alternatives for the service desk to use.

It's basic features are:

  • A very simple interface and instructions
  • A basic and somewhat unique password is generated
  • A "pronounceable" version of the password is created in the NATO alphabet for speaking over the phone
  • The password is copied to the clipboard (IE only) for pasting into whatever reset tool is in use
There are two versions, the first generates a strong random password, and the second uses one of a list of weak base words, with random numbers put on the end. The second was created after push back from the service desk agents saying that user's were complaining about the random passwords. I don't like the second version, because it is still fairly predictable, and someone internally could pull out the passwords and create a simple password list to feed to any number of tools. If you are going to use the second version, please use your own list of words, ideally several thousand to increase the entropy. The current list was created by taking the top 500 6-digit words from the Unix English (en) dictionary, and removing complex ones.

These tools where originally written when I was an employee of Deloitte South Africa, and while necessarily under the GPL due to included code, are still published here with permission of them. They have however, been updated since then on SensePost's coin.

Tue, 9 Mar 2010

Decrypting Symantec BackupExec passwords

BackupExec agent is often among common services found on the internal pen tests. The agent software stores an encrypted "logon account" password in its backend MS SQL database (LoginAccounts table). These accounts include the "system logon account" which is used to run agent services and an optional number of active directory accounts that are used to access resources over the network. The following scenarios can result in access to encrypted passwords:

1- Backend MS SQL database compromise (database name is BEDB by default)

2- Access to BackupExec installation directory: A daily MS SQL backup job on BEDB database is run by BackupExec and the resulting backup file is stored as data/bedb.bak file under BackupExec installation directory. The backup file containing encrypted passwords can be restored on another system.

Encrypted passwords are 512 bytes long and the agent software decrypts them using bemsdk.dll file. The following C code can be used by to quickly decrypt the ciphers:

BackupExec decryptor

The above code has been tested with BackupExec 10.0.5484 (SP5) and should be working with other versions of BackupExec (Source code for the above program, you'll need a copy of the .dll).

Fri, 5 Jun 2009

Two quick links on "how your app got hacked, even though it looked ok"

The first one from hacker news, aptly titled "How I Hacked Hacker News (with arc security advisory)"

and the 2nd, a welcome-back-to-the-blogosphere-tptacek post on the matasano blog: [Typing The Letters A-E-S Into Your Code? You're Doing It Wrong!]

/mh

PS. for those going, man i wish someone would break down the important crypto stuff for me in a way thats understandable without being patronizing, there is Chris Eng and his owasp talk on [Cryptography For Penetration Testers]