A blog by Graham Smith

I decided to open source my basic file format fuzzer. It needs some work, however, it is capable of producing meaningful crashes. Enjoy!

Configuration

There are several things that must be done to setup New York.

First of all, you will need to edit debug.bat to replace <command> with the command you want to run. Feel free to move around %1, which is the filename argument passed from nyc.go. It is only placed where it is based on standard command line calling convention. An example of how debug.bat might look is as follows:

windbg -G -Q -c "$$><events.wds;g" "program.exe" %1

If the target process is in your path, feel free to shorten debug.bat to something like this:

windbg -G -Q -c "$$><events.wds;g" program %1

No changes are necessary to nyc.go, cpu.bat, or events.wds, but they are simple enough to alter if need be.

Secondly, make sure before running nyc.exe that crash.log does not exist in the same directory as the New York executable.

Lastly, you will need a fileset. My scraper isn’t up to par at the moment, but scraping mmnt.ru should suffice, especially when searching for obscure filetypes that aren’t necessarily indexed by the major search engines. Your best bet is creating a minset by tracing codepaths with a tool such as RunTracer.

Compilation

No external dependencies are required. Ensure you have the latest version of Go installed (version 1.5 at the time of writing). Versions 1.5+ have support for non-bootstrapped cross-compilation, so compiling on your host for use within a x86 or x64 VM should be no problem. To compile for your default architecture, run the following:

go build neuebits.com/neuegram/newyork

In order to cross-compile, you must set the environment variables GOOS and GOARCH to the corresponding values for the target. Then you may continue with running the command above.

Usage

Generic: nyc.exe <target process> <minset> <filetype> <timeout>

Example: nyc.exe program.exe minset .mp3 10

Process Termination

It’s important to note that if <timeout> <= 0, then the process will be terminated when the process’ CPU usage is 0. Otherwise, the process will be terminated after it has been detected as running (CPU usage not 0 or -1), in addition to the specified delay.

TODO

Log errors to a file

Central server distribution of mutations

Central server controlled rolling restarts

Implement different methods for “dumb” fuzzing / mutation

Protocol fuzzing (in real time and from pcaps)

Linux support

Mac OS support

A lot more…

Contact / Hire Me

I had promised myself earlier in the year I would find the time to learn more about reverse-engineering iOS applications. For convenience, I use iOS when capturing packets, and Android for static analysis, instrumentation, and swizzling. With a little post-Thanksgiving free time on my hands, I figured why not spend some of it playing around with Cycript.I thought I would write a simple introduction based off of my own first experience with Cycript.

I decided to target iPGMail, a PGP client for iOS that hides behind its own lockscreen.

I began by launching iPGMail, which prompted me for my previously established PIN in order to access the rest of the app. At this point, I tested to make sure that an invalid PIN would be rejected. Wanting to find the function call that performed this validation, I created a dump of the decrypted binary using Clutch iPGMail. Clutch is a tool to dump a decrypted binary for third-party apps. I then unzipped the resulting .IPA to a new folder with unzip iPGMail.ipa -d iPGMail.

From here, I used class-dump-z -H iPGMail/Payload/ipgmail.app/ipgmail -o iPGMailHeaders to dump the class headers to a new folder. Searching through the contents of the resulting headers, I discovered the function responsible for PIN validation (-(BOOL)checkPin:(id)pin) within iPGMailAppDelegate.h. I swizzled its message implementation by using cycript -p ipgmail to attach and iPGMailAppDelegate.messages['checkPin:'] = function() { return true; } to guarantee that any provided PIN would suffice.

Overall, Cycript is an extremely helpful tool to have around and is great for testing jailbreak tweaks among other things. Also, check out Frida. Both can be used without a jailbreak and I definitely see myself becoming a frequent user of these tools.

Something that has recently caught my attention is poor security practices in regard to software updates. One of the best things you can do to protect yourself is to update your software, but what happens when automatic or manual updates themselves open you up to other attacks?

Take for example Silver, an open-source project from PaperCut, creators of print management software “used by over 50,000 organizations worldwide.” I am told that “the project that uses Silver is not public yet - [Papercut] plan[s] to launch next year.” Let’s examine PaperCut plans to use Silver to “host an agent service installed at customer sites that needs to operate reliably with zero on-site maintenance and configuration.”

If we were to MITM the request made by checkUpdate(), we can force an update / downgrade by supplying a malicious JSON response with any version different than the current version running on the system. A quick xref for checkUpdate() reveals a single call made by the following function:

A malicious JSON response also allows us control of the download URL for the update / downgrade. Checksums are optional, although with a MITM that would not make the slightest difference. Not only that, but it seems we have quite a few options for (arbitrary) commands: exec / run, batchrename / batch-rename, move / mv, copy / cp, remove / rm / del / delete. We see that the exec / run opcode triggers a call to the following function:

We will be releasing an updated version of the Snapchat application that will allow Snapchatters to opt out of appearing in Find Friends after they have verified their phone number. We’re also improving rate limiting and other restrictions to address future attempts to abuse our service.

January 3, 2014 (10:45PM PST) - I reached out to Snapchat because of a flaw that left Find Friends vulnerable in spite of rate limiting and other quick-fixes they made

January 3, 2014 (11:38PM PST) - Micah Schaffer promptly replies on behalf of Snapchat, “willing” to work on fixing the problem

January 7, 2014 - After several days of radio silence from Snapchat and no clear signs that they were working on a fix, I decided to take the matters into my own hands. I found Bobby Murphy (Co-Founder & CTO @ Snapchat) in the database released by snapchatdb.info, his number appearing with a simple query for the username bobby. Doubtful that Snapchat was working on a fix, I used the vulnerability to confirm the last two digits of his phone number in a matter of seconds.

January 7, 2014 (3:39PM PST) - I decided to call Bobby, only to receive his voicemail. I texted him. Hey Bobby. He texted back. Who is this? So I filled him in on the details and was told to send him an email and he’d see what he could do.

January 10, 2014 (2:00PM PST) – I had an interview at Snapchat for a position as software engineer. This was for an open position and I was competing against college students, mostly junior-year CS majors (probably) from top-tier schools. I had this interview thanks to Bobby, but I completely wasted the time of their poor Android engineer, Nic. When it came to the programming challenge, all I had to do was validate a Sudoku board, which was stored in a 2D array. The challenge was quite simple, in fact, I had solved it before in the past. However, I had never interviewed for a job before, let alone done a programming interview. I cracked under pressure. Wasted both of our time. Yet somehow, as soon as our Google Hangout ended, I was able to solve that programming challenge in under five minutes. Overall, the process was a good experience because I learned a little about myself and about programming interviews.
January 13, 2014 - I began looking into Snapchat’s ”updated version of the Snapchat application that will allow Snapchatters to opt out of appearing in Find Friends after they have verified their phone number.” As it turns out, phone number verification is only an in-app requirement. There wasn’t a single server-side check to see if an account has been validated, meaning you can programmatically use Find Friends on a brand-new account, no phone number verification required. Additionally, forcing users to verify phone numbers before using Find Friends or opting-out of Find Friends defeats the intended purpose of the validation. Therefore, if users validate without opting-out or the Snapchat database is hacked, then every user that ever validates could have their phone number compromised.

January 13, 2014 (2:57PM PST) - After texting Bobby, he acknowledged that they don’t make a server-side check.

January 19, 2014 - I’m not completely positive this is the correct date, but I’ve heard that this is the date that Snapchat decidedly rolled out SNAPTCHA. SNAPTCHA is an obscure and fun version of the CAPTCHA that has users confirm they are human by selecting a photo that contains the famous Snapchat “ghost” logo.

January 22, 2014 - I completed my script for solving SNAPTCHA’s, but have no plans on releasing the code because I don’t want to be held responsible for a second dump of users’ phone numbers