Live365: How you too can become a VIP

So I got a new laptop and installed Linux on it. Due to an unknown reason (flash player not working, no support for the best browser, etc.) I was not able to listen to one of my favorite internet radio stations on the Live365 website. Not only that, but they don’t provide a link to listen to the station in an external player, at least not without registering.

Well you know what that means: reverse engineering time.

For this example we’ll be using Electronic FM as our target station, because it’s awesome. Let’s look at what we have to start:

Well the audio stream has to end up going through the player widget, so that seems like a good place to start. Let’s look at the requests in Chrome’s inspector and see if we can pick out the player widget.

The streamer301 SWF seems like a reasonable target. Decompile it using www.showmycode.com.

We see what looks to be a custom MP3 decoder which gets passed a stream URL from elsewhere. That means the application code has to generate that URL and pass it in. The simplest way to do this is via FlashVars which are present when the SWF is embedded. Looking through Chrome’s inspector again we find:

The only variables here look like ones which control bitrate, volume and such. That means the stream URL is generated via JavaScript and passed in. Let’s look for URL in the scripts by searching for it in the “Resources” section of the web inspector.

So it looks possible but it looks like we need the stream ID, which could be both problematic and annoying to fetch. Let’s see if we can do better by taking another approach. Live365 lets you embed a player widget on your own website, which must also play the appropriate stream. Perhaps this widget will contain useful information. The player widget can be accessed by clicking the gear icon on the main page.

We take the same approach as with the first SWF and have a look for it in the list of requests the page has made.

Again, we decompile it. Let’s look for stuff talking about URLs. Eventually we come across the following function:

Aha! It even looks they have a setting for controlling VIP access! However, we don’t know where the first argument comes from yet. If we change our search to look for references to that particular function we find:

That it’s just the station name! How easy!

So if you open this URL in your favorite media player you can listen to Electronic FM. VIP. For free. No registration required.

http://www.live365.com/play/efmradio?tag=vip&session_id=&device_id=&app_id=live365:Widget365&caller=live365:Widget365

You can replace “efmradio” with the station name of your choice.

LucidChart + JavaScript: Breaking limits with AJAX hijacking.

Update: As it turns out the people at LucidChart work as well as their product and I received some e-mail:

I ran across your blog post this morning and wanted to quickly reach out. Thanks for the compliments on LucidChart — glad to hear you’re enjoying the app! We’d love to hear any feedback you have on how we can continue to improve it going forward. On that note, we have to be able to make money to keep the product available and continue to make it better. The Chrome extension that you’ve written can really hurt us. Would you please take down the blog post and not distribute the Chrome extension? There are certainly a number of safeguards we can put into place to prevent the hack from working but we’d prefer to spend that time making the product better for you and our other customers.

After some back and forth they have closed this hole and sent a kind reminder that for those who are cash-starved students: you can obtain the professional version for free.

With that in mind the techniques present here can still be used to manipulate AJAX requests from any source.

LucidChart is the best online diagramming software I have used hands down. Why? It works. It looks nice. It’s not written in Flash (basically every other charting tool: Gliffy, Creately, LovelyCharts, etc). Granted, it has a ways to go before it becomes competitive with the likes of OmniGraffle, but for a web-based solution it’s still very usable.

Unfortunately you’re stuck with being able to put at most 60 objects into your scene with the free (non-trial) account.

We note there’s a little meter labeled “Complexity” which tracks the total number of objects in the scene divided by the total number of maximum allowed objects. That means each time an object is added it must make a calculation against our limit.

Seems like a good place to start hunting for where the limit ends up being set. Open the Web Inspector for that element.

And we end up with the following result:

With trivial insight, in this case, you can see the width of the element is not a whole number which means in all likelihood their calculation works something like Current Objects / Total Allowed Objects * Complexity Container Width. We know the div has an id of “complexity” so we now have to go find out what references that. Time to take out the scripts.

You can see lots of scripts that this page uses, and it takes a little bit to search through all of them, but “lucid.js” seems like a good place to start. Unfortunately, just looking at the path and the file’s contents it looks like the script was generated using Google’s Closure tools. That makes things overly messy and hard to sort through. Thankfully Chrome can undo some of that mess.

Click on the curly braces and like magic all the code will become formatted with spaces and indenting. Wonderful. Next, we need to search for references to complexity. Simply enter it in the search box.

There are quite a few references, but the one we’re interested in looks something like this:

Looking back at our guessed formula, there seems a reasonable candidate here. “document.lg” is divided by “da.Level.document_objects”. So now we need to figure out where “da” gets set from. Back to the search bar.

We include the “=” sign in the search because we’re really only concerned where “da” gets assigned a value. After going through a few of them you will probably come across this little gem:

So they’re using a standard jQuery AJAX request to fetch session data. Well we can find that using the Network panel in the Web Inspector.

And if we look at the content in that file:

Looks like our cap is coming from this request. So the basic approach is simply going to involve stealing that request before it gets passed to the application and overwriting any values we like. Unfortunately this is harder than it sounds. The approach we’re going to take will involve creating a Chrome extension to do the dirty work. Create a folder and in it place a file named “icon.png” to represent your application’s icon; then create 2 files named “background.js” and “manifest.json”.

The manifest file describes our extension. We can use the following JSON for our purposes:

{
	"name": "Lucid Unlimited",
	"version": "1.0",
	"icons": {
		"48": "icon.png"	
	},
	"description": "Play with Lucid Charts.",
	"content_scripts": [{
		"matches": [ "https://www.lucidchart.com/*" ],
		"js": [ "background.js" ],
		"run_at": "document_start"	
	}],
	"permissions": [
		"https://www.lucidchart.com/*"
	],
	"manifest_version": 2
}

It’s pretty self-explanatory. Content scripts are scripts which get attached to the page (in our case we want the hijack script to run before anything else and only on LucidChart pages). Permissions describe on which pages our extension should be allowed to run.

Fire up developer mode for Chrome extensions and load your unpacked extension.

Hijacking the AJAX request is a tricky feat, mostly because Chrome extensions run in “isolated worlds”. While your extension can access the DOM (i.e. manipulate elements on the page) it CANNOT overwrite other variables set by the page. To do hijacking we unfortunately need to do this. After some thinking you too might come to the elegant conclusion: if we can manipulate the DOM, and the DOM can run “script” elements outside the extension’s isolated world then we might just have something.

function injectScript(source) {
	var elem = document.createElement("script"); //Create a new script element
	elem.type = "text/javascript"; //It's javascript
	elem.innerHTML = source; //Assign the source
	document.documentElement.appendChild(elem); //Inject it into the DOM
}

//Test it
injectScript("alert('hello world');");

This creates a bit of an inconvenience though because it means the code we inject has to be a string. It’s far from elegant trying to cram all your patch code into one string, so why not make something that will generate that string for us and let us code like we normally do? We can use the “toString” method of a function to generate all the code for that function.

injectScript("("+(function() {
	alert("Hello world!");
}).toString()+")()");

So now that we’re out of our isolated world, we can really get to work. In order to hijack an AJAX request we need a hook every time it’s created. Overwriting XMLHttpRequest’s “open” method will do the trick.

injectScript("("+(function() {
	//Save the old function
	var proxied = window.XMLHttpRequest.prototype.open;
	//Overwrite with a new one
	window.XMLHttpRequest.prototype.open = function(method, path, async) {
		console.log(arguments); //Log for debugging
		return proxied.apply(this, [].slice.call(arguments)); //Call the old function
	};
}).toString()+")()");

Save the extension and you should see lots of output on the console. You can use this as the basis for intercepting any AJAX request you feel so inclined to.

However, since we only want to mess with the requests we care about, we’re going to have to install a simple check that makes sure we’re getting at the session data.

injectScript("("+(function() {
	//Save the old function
	var proxied = window.XMLHttpRequest.prototype.open;
	//Overwrite with a new one
	window.XMLHttpRequest.prototype.open = function(method, path, async) {
		if (path.match(/\/users\/userSession/)) {
			console.log(arguments); //Log for debugging
		}
		return proxied.apply(this, [].slice.call(arguments)); //Call the old function
	};
}).toString()+")()");

Running it again should result in only the request for the user session being output. Once we have the request we’re interested in, we want to listen for when a response actually comes in. We can accomplish this by adding an event listener. It’s important that useCapture is enabled so that we are always the first person to receive the event due to the way DOM event bubbling works. We listen for when the state of the request changes, and it can change for reasons other than just the content being loaded, so we need to make sure we only do our work when the content is actually ready for us. The state “4” happens to be the one in which the request has completed.

injectScript("("+(function() {
	//Save the old function
	var proxied = window.XMLHttpRequest.prototype.open;
	//Overwrite with a new one
	window.XMLHttpRequest.prototype.open = function(method, path, async) {
		if (path.match(/\/users\/userSession/)) {
			this.addEventListener('readystatechange', function() {
				if (this.readyState === 4)
					processUserSession(this);
			}, true);
		}
		return proxied.apply(this, [].slice.call(arguments)); //Call the old function
	};
}).toString()+")()");

function processUserSession(request) {
	console.log(request.responseText);
}

Running this, we can see the response is a JSON string. We can use “JSON.parse” to turn it into an object we can work with. And once we can work with it, it means we can set any variable we want, including the one that controls the limit on the number of objects in the scene! Once we’ve done that we just turn our object back into JSON and it’s like nothing ever happened.

function processUserSession(request) {
	var data = JSON.parse(request.responseText);
	data.User.Level.document_objects = 0;
	console.log(JSON.stringify(data));
}

Unfortunately “response” and “responseText” are read-only variables. We can’t assign new values to them. However, there is a neat little trick where we can proxy their true values by defining a getter on top of the original variables. In this case we’re going to override “responseText”.

function bindResponse(request, response) {
	request.__defineGetter__("responseText", function() {
		return response
	})
}

Adding it into our code we get:

function processUserSession(request) {
	var data = JSON.parse(request.responseText);
	data.User.Level.document_objects = 0;
	bindResponse(request, JSON.stringify(data));
}

Interestingly enough the complexity meter disappears for a little, but reappears again. Either we’ve set the wrong variable, or there’s another variable that needs tweaking. If we dig a little deeper into the code we realize there’s also a “chat” command that sets something with an access level type object. We can apply the same trick to the new “chat” request; putting it all together we get this.

function injectScript(source) {
	var elem = document.createElement("script"); //Create a new script element
	elem.type = "text/javascript"; //It's javascript
	elem.innerHTML = source; //Assign the source
	document.documentElement.appendChild(elem); //Inject it into the DOM
}

injectScript("("+(function() {

	function bindResponse(request, response) {
		request.__defineGetter__("responseText", function() {
			return response;
		})
	}

	function processLevel(level) {
		level.document_objects = 0;
		level.watermark = 0;
	}

	function processUserSession(request) {
		var session = JSON.parse(request.responseText);
		processLevel(session.User.Level);
		bindResponse(request, JSON.stringify(session));
	}

	function processChat(request) {
		var chat = JSON.parse(request.responseText);
		processLevel(chat.level);
		bindResponse(request, JSON.stringify(chat));
	}

	var proxied = window.XMLHttpRequest.prototype.open;
	window.XMLHttpRequest.prototype.open = function(method, path, async) {
		if (path.match(/\/users\/userSession/)) {
			this.addEventListener('readystatechange', function() {
				if (this.readyState === 4)
					processUserSession(this);
			}, true);
			
		} else if (path.match(/\/chats\//)) {
			this.addEventListener('readystatechange', function() {
				if (this.readyState === 4)
					processChat(this);
			}, true);
		}

		return proxied.apply(this, [].slice.call(arguments));
	};
}).toString()+")()");

Now there is no more complexity bar and you can use as many objects as you like.

You can use the extension developer tools “Pack extension” tool to create a proper extension.

Exploring Cramster: How Flex & a brain can get you answers to all your textbook questions.

So I came across a website called Cramster while on the search for resolving some ambiguity about the count-to-infinity problem in distance-vector routing. I came to realize quickly that their textbook answers section functions similarly to overlords in StarCraft 2:

That is to say said section acts like a giant retard magnet. People are drawn out, enticed by the hope of easy answers to their homework problems, only to be met by the giant army of “herp derp you need to pay for every even question”. Given the magnet attracts retards in the first place it’s not hard to see them paying for this stuff and Cramster making tons of money. But we can do better. We’re reverse engineers.

Well, you wonder, is there a way we might be able to get those secret even numbered answers? Of course there is! Cramster has employed security by obscurity which, as you and I know, never, ever works. So let’s start!

First off, we want to figure out how the odd answers work and maybe that will give us some insight into how the even answers work. You’ll need to register for Cramster before you can start this whole process, so do that and then we’ll need to select a textbook to test. Pick any from their list of textbooks here. I have chosen “Introduction to Algorithms“, mostly because algorithms are pretty awesome. We note the list of chapters and questions we can select a solution for. 3P seems like a good chapter with about 6 questions to choose from.

Let’s have a look at the first question. We can see the result displayed, but trying the second question yields that horrible “you can only view odd questions” garbage. Let’s go back to taking apart what we can see with that first question.

Oh look! Flash! How not lovely. If we open Chrome’s developer tools, (Tools > Developer from the menu), select the network tab and refresh the page we can see where this SWF is coming from. Sorting by type, simply look for those of type “application/x-shockwave-flash”.

We can see something like “3_P-1P-Step1_96.swf”. We kind of assume that it’s the first step in the answer to the first problem. Let’s double click it to open it and see if it displays what we want! We get taken back to Cramster…

Alas, they have some tom foolery embedded into their answer file. But it’s Flash, and Flash can be decompiled. Since we’re only interested in this one file we can use http://www.showmycode.com/ to decompile the SWF. Copy and paste in the URL of the SWF.

Once you hit decompile: Bam! Code!

Looking into it we can see that on the 5th frame it causes the browser to redirect to Cramster’s site! Aha! Found your devious little plot. Not only that, but we see a function called getContent() that returns bitmap data AND stops the animation so that it never redirects. It seems somewhat likely that this bitmap data is the image of the answer we’re looking for and that a parent SWF calls this function.

To work with controlling SWF files we can use Flex. We’ll try and pull the URL directly from our app and display it. Download and install FlashDevelop and create a new project.

You can pick Flex 4 when it asks what kind of project you want.

So let’s look at putting our known answer in there and defeating the very basic redirect protection they’ve come up with first. We know it yields bitmap data, so we can use a bitmap image element to display it! Because we’re all object-oriented programming badasses we’ll make a class for loading it up. Crease a new AS3 file and save it as “StepLoader.as”.

Your setup should look something like this:

Important! Make sure you right click your “Main.mxml” file and have “Always compile” selected.

package
{
	import flash.events.Event;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.display.Bitmap;

	import spark.primitives.BitmapImage;
	import spark.components.Group;

	/**
	 * Class for loading Cramster answer steps.
	 */
	public class StepLoader {

		/**
		 * Area where the step is to be added to.
		 */
		private var display:Group;

		/**
		 * Create a new loader, initialize the object and start fetching
		 * the data!
		 */
		public function StepLoader(g:Group) {

			//Assign object variables.
			display = g;

			//Create a new loader.
			var loader:Loader = new Loader();

			//Create the URL request for the step.
			var req:URLRequest = new URLRequest("http://s3.amazonaws.com/step-by-step-as3/337/3_P-1P-Step1_96.swf");

			//Set event handler to trigger when the data has finished loading.
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);

			//Actually fetch the data
			loader.load(req);
		}

		/**
		 * Called when the remote SWF has been successfully loaded.
		 * @param e Event containing information about the loaded SWF.
		 */
		private function onComplete(e:Event):void {

			//Create a new bitmap image.
			var img:BitmapImage = new BitmapImage();

			//Fill that image with the data obtain from the downloaded SWF by using
			//the discovered getContent() function.
			img.source = new Bitmap(e.target.content.getContent());

			//Add it to the display
			display.addElement(img);
		}
	}

}

And we also need to edit the Main.mxml file to use this new class as well!

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
			   applicationComplete="init();">
	 <fx:Script><![CDATA[	
		private function init():void {
			new StepLoader(steps);
		}
  ]]></fx:Script>
	<s:layout><s:VerticalLayout /></s:layout>
	<s:Scroller width="100%" height="100%" minViewportInset="1" focusEnabled="false">
        <s:Group id="steps" clipAndEnableScrolling="true">
			<s:layout><s:VerticalLayout /></s:layout>
        </s:Group>
	</s:Scroller>
</s:Application>

Compile, run and oh hey look! We can display the first step in the answer to the odd question!

So how can we get the even ones in there? Well let’s go back and have a look at that URL.

We can start making some assumptions about its nature. We know it’s hosted on Amazon’s CDN, S3 (which means all the data is likely public). We can figure pretty obviously that “3_P” is the chapter (from the 3.P we selected), “1P” is the first problem, and “Step1″ is the first step. What about the 337 at the start and the 96 at the end? Digging around a bit we can surmise that 337 is the numeric ID of the textbook we selected!  Remember that textbook URL? http://www.cramster.com/introduction-to-algorithms-2nd-solutions-337. Oh look. Funny how that 337 just happens to pop up there! So that just leaves us with 96. Unfortunately it has no immediately correlated data.

So let’s change our app so that we use variables to construct the URL and replace the parts accordingly. We’ll also add a form so the user can enter in which textbook, chapter and problem they want.

package
{
	import flash.events.Event;
	import flash.display.Loader;
	import flash.net.URLRequest;
	import flash.display.Bitmap;

	import spark.primitives.BitmapImage;
	import spark.components.Group;

	/**
	 * Class for loading Cramster answer steps.
	 */
	public class StepLoader {

		/**
		 * Area where the step is to be added to.
		 */
		private var display:Group;

		/**
		 * Textbook id.
		 */
		private var textbook:int;

		/**
		 * Chapter id.
		 */
		private var chapter:String;

		/**
		 * Problem id.
		 */
		private var problem:String;

		/**
		 * Step number.
		 */
		private var step:int;

		/**
		 * Create a new loader, initialize the object and start fetching
		 * the data!
		 */
		public function StepLoader(g:Group, t:int, c:String, p:String, s:int = 1) {

			//Assign object variables.
			display = g;
			textbook = t;
			chapter = c;
			problem = p;
			step = s;

			//Create a new loader.
			var loader:Loader = new Loader();

			//Create the URL request for the step.
			var req:URLRequest = new URLRequest("http://s3.amazonaws.com/step-by-step-as3/" + textbook + "/" + chapter + "-" + problem + "-Step" + step + "_96.swf");

			//Set event handler to trigger when the data has finished loading.
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);

			//Actually fetch the data
			loader.load(req);
		}

		/**
		 * Called when the remote SWF has been successfully loaded.
		 * @param e Event containing information about the loaded SWF.
		 */
		private function onComplete(e:Event):void {

			//Create a new bitmap image.
			var img:BitmapImage = new BitmapImage();

			//Fill that image with the data obtain from the downloaded SWF by using
			//the discovered getContent() function.
			img.source = new Bitmap(e.target.content.getContent());

			//Add it to the display
			display.addElement(img);
		}
	}

}
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
			   applicationComplete="init();">
	 <fx:Script><![CDATA[	
		private function init():void {
			
		}
		
		private function processForm():void {
			steps.removeAllElements();
			new StepLoader(steps, parseInt(textbook.text), chapter.text, problem.text);
		}
		
  ]]></fx:Script>
	<s:layout><s:VerticalLayout /></s:layout>

	<mx:Form defaultButton="{submit}">
		<mx:FormHeading label="Cramster Solutions" />
		<mx:FormItem label="Textbook:">
            <mx:TextInput id="textbook" />
        </mx:FormItem>
		<mx:FormItem label="Chapter:">
            <mx:TextInput id="chapter" />
        </mx:FormItem>
		<mx:FormItem label="Problem:">
            <mx:TextInput id="problem" />
        </mx:FormItem>
		<mx:FormItem>
            <mx:Button id="submit" label="Get Solutions" click="processForm();"/>
        </mx:FormItem>
	</mx:Form>


	<s:Scroller width="100%" height="100%" minViewportInset="1" focusEnabled="false">
        <s:Group id="steps" clipAndEnableScrolling="true">
			<s:layout><s:VerticalLayout /></s:layout>
        </s:Group>
	</s:Scroller>
</s:Application>

Run it!

Hey! We can get answers for the even numbered solutions. Fancy that.

The basics are pretty much done. We can easily improve our application to make it a little easier to use by doing things like displaying all the steps at once. Since we don’t know how many steps a solution has, we simply has to keep looping until we cannot retrieve a step. It’s a bit of a kludge but it works. Our class is already perfectly designed for this. We just need to add a bit of recursion.

		/**
		 * Called when the remote SWF has been successfully loaded.
		 * @param e Event containing information about the loaded SWF.
		 */
		private function onComplete(e:Event):void {

			//Create a new bitmap image.
			var img:BitmapImage = new BitmapImage();

			//Fill that image with the data obtain from the downloaded SWF by using
			//the discovered getContent() function.
			img.source = new Bitmap(e.target.content.getContent());

			//Add it to the display
			display.addElement(img);

			//Fetch the next step
			new StepLoader(display, textbook, chapter, problem, ++step);
		}

Try it out!

And after all that, you now have a Flex app that can view just about any Cramster textbook answer you feel compelled to get. Awesome? I think so!

As a further exercise to the reader one could add displaying ratings and comments. If we go back to that network window we can see some data with type “text/xml” and if we have a look at it, it seems to be data from a SOAP web service located at http://www.cramster.com/webservice/solutionplayer.asmx. Look at all these goodies! Flex has SOAP support built in, which is great. To figure out how to use it we can just have a look at the API documentation for it. We’ll just add that to our Flex app and it now supports ratings and all those other SOAP services offered by Cramster! You could also tie it all together by stripping some useful information out of their HTML and populating some Flex fields for ourselves (like listing the chapters of problems for a textbook).

Until next time!

FreePhoneLine and Tom – A Truly Deep Reverse Engineering Adventure!

Update: I have received an email requesting the use of this quote as to the one I had previous:

Thank you Izaak, this is brilliant work. Prior to coming here I had no experience in programming, servers, or the tools used here as outlined in your method. I know you get a lot of requests to (and it would have saved time if you) ‘spoon feed’ the answer but I understand that position is not one you want to be in for legal reasons. What you have outlined in these 2 posts has been deeply entertaining, educational AND effective. It does work and anyone who follows the instructions and doesn’t get their answer should go back and read it again. The answers are all here. For a tool (Apache) I didn’t understand how to set up I simply Googled it – there was an instructional video on youtube. Izaak you’ve already been very generous with your time and I look forward to your next projects. To everyone else – this isn’t easy stuff but if you do the work to learn you might be rewarded in more ways than simply expanding your mind.

At that request, I have kindly made it slightly more challenging to achieve this article’s goals.

Update: Many people have asked if this code still works, and it does. In fact, a pure HTML/Javascript implementation is possible.

Note: If you haven’t read the previous post related to this subject, you need to do so before you can make sense of any of this. This article is long and complicated and not for the faint of heart. It is, however, terribly fun!

So I was minding my own business, as usual, until I received this email:

Dear Mr Schroeder!

My name is Tom Shao from Canada. I was excited that you can reverse Engineering Java and obtain the secret password. Your instruction in the weblog is very detailed. However I don’t have eclipse installed on my desktop. I just wonder if you can do me a favor to help me get my password. My information is as follows:

[Omitted for obvious privacy reasons]

Any help would be much appreciated.

Thanks,

Tom

Now normally I don’t go off and just do work for people asking for stuff, given it’s supposed to be a learning experience; not a “hurr hurr give me free stuff” experience. However, only a few hours later I receive ANOTHER email!

I downloaded Eclipse and tried to debug it with no lock [sic] as the class KC is different with yours. I assume they updated the new version and fixed the problem.

Can you send me your Freephoneline software? I am desperate to need your help?

Thanks,

Tom

So you at least get some points for trying. As it turns out, they did indeed update their software, but it certainly wasn’t to “fix” that problem; in fact if anything they turned their program from a reasonable softphone client to a horrendously ugly (like I’ve taken shits that look better kind of ugly), slow, ad-filled piece of garbage.

The reason you can’t exactly follow my previous post is that the obfuscation process randomizes class names, methods and so on; every time they release a new version you will end up with a different naming scheme. The process of finding your credentials works the exact same way in the new version, introducing a manual break in the program and hunting through the class variables until you find the password.

But all is not lost for you Tom! I will help you redeem yourself! I have provided a handy comparison chart for the rest of our readers:

Thanks to you Tom, (but mostly me), other people now too can have free calls with little effort! This blog post covers something a bit more interesting and useful than what was discussed previously. It deals with discovering the FreePhoneLine authentication protocol itself and how to emulate it; it also exposes a possible security hole in that particular protocol.

Shall we find out?

Let’s start with what we know. You provide your FreePhoneLine username and password, which gets sent to the server and they send you your SIP username and password back; all of this is encrypted and therefore one can’t simply WireShark the information off the network.

We want to be able to achieve two things:

  1. Be able to construct the appropriate request to get our encrypted username/password
  2. Be able to decrypt the response so that we may use our SIP username/password

We’ll start things off the same way we did the previous article, breaking the program and finding out which class holds the clear-text password, and from there which class actually decrypts the password to its clear-text form. I’m not going to bore you with old hat; setup the project the same way as before and use the same techniques achieve the following result:

We’ve discovered that the class called “f” contains the connection information; particularly of interest are fields “e” and “g” which hold the SIP username and password respectively. We’re interested in finding out what modifies those variables; since they are public variables, (denoted by the green circle), they can be modified by any class; so we can use a feature in Eclipse very similar to a breakpoint called a watchpoint!

Watchpoints monitor variables; they will pause the execution of the program when a variable is read from, written to or both. Those familiar with x86 debuggers will note a similar feat can be achieved with hardware breakpoints. To set a watchpoint, find the class in the package viewer and select “Toggle watchpoint”.

Close the program if it’s being run and start debugging it again. The program will suspend immediately and drop you back into the debugger. What’s happened? The password isn’t being loaded in so soon obviously, as we have not even logged in yet. The answer is disappointingly simple; the variable is simply being initialized to null, (i.e. the program is writing null into the variable). We can just resume the program. But wait! It pauses again! What’s going on this time? Again, the answer is disappointingly simple. The variable is being set to the empty string “”. Remember! Null is not the same as the empty string! The empty string is still a string object, the null string is nothing. You can see this by hitting the “Step over” button and you can watch “g” change from null to the empty string.

Anyway, we can go back to running the program and you should be able to hit up the login box and enter your credentials before the program breaks you back into the debugger again. You should then end up with something like the following:

This looks promising! You’ll note if you look in the variables view that the field “g” still does not have your password. That means if we hit “step over” your password will suddenly appear! That’s because something within “wo.c” (remember, “c” is a method of the class “wo”) is saying “g = SIPPassword”. That’s the whole purpose of a watchpoint. So we basically want to understand what goes on inside “wo.c” that is setting our password.

But how on Earth do we begin to do that when we don’t have any source code to work with? Well, we just make source code! Using a tool called a decompiler we can turn a Java “.class” file back into a “.java” file! Pretty impressive! Not all decompilers were created equal, and a lot of semantic information is lost in the decompilation process, but the result is still extremely useful!

I have chosen to use a Java decompiler called JD. (Original name, eh?) You can get your copy here. Extract “JD-GUI”, and run it. Open the “wo.class” file with it.

And then find the “c(ActionEvent)” method within it. There’s a lot of code in that class, so I won’t bother pasting it all. I will, however, highlight a few parts that tell us we’re probably going in the right direction!

String str1 = this.a.getText();
String str2 = String.valueOf(this.i.getPassword());

See that “getPassword()” there? That’s probably getting the password you entered, and the “getText()” above it is probably fetching your username! And as we scroll down that code chunk:

this.l.e = zc.d();
this.l.g = dc.a(zc.f(), this.l.e); //THIS LINE TRIGGERED OUR WATCHPOINT! l.g IS ASSIGNED HERE!
setVisible(false);

And once you see it visually the correlation becomes even more obvious:

We can make an educated guess that “zc.d” fetches the username, “zc.f” fetches the encrypted password and “dc.a” handles the decryption! And once everything is done the login windows calls “setVisible(false)” to hide itself from view. Things are coming together nicely! In JD simply click on the underlined “dc” class and we can start checking out the “dc.a” function.

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

When you see things like that at the top the file, you just know you’re in the right spot; they’re using standard ol’ Java cryptography APIs! That will make things even easier on us because all those APIs are very well documented. We can check out the rest of the file and we realize that there are a few functions called “a”. The one that’s being called takes two arguments.

this.l.g = dc.a( //returns a string because l.g is a string, obvious from the debugger
    zc.f(), //we don't know this type; we could check the return type of zc.f though
    this.l.e //this is a string type, obvious from the debugger
);

But since this function, “dc.a” is called from “wo.c”, we know that whatever particular “a” is being called also needs to be a public method! This narrows it down to just one function:

public static String a(byte[] paramArrayOfByte, String paramString)

Which we observe basically only does one important thing:

byte[] arrayOfByte = a(false, paramArrayOfByte, paramString);
return new String(arrayOfByte).trim();

It calls ANOTHER a and returns its value in string form! That particular “a” is easily identifiable as being the only one which takes a boolean argument initially.

private static byte[] a(boolean paramBoolean, byte[] paramArrayOfByte, String paramString)
{
    int i = cc.c;
    byte[] arrayOfByte1 = a(paramString);
    SecretKeySpec localSecretKeySpec = new SecretKeySpec(arrayOfByte1, z[1]);
    Cipher localCipher = Cipher.getInstance(z[2]);
    IvParameterSpec localIvParameterSpec = new IvParameterSpec(z[0].getBytes());
    //...
}

Is obviously the most interesting one; it actually makes use of cryptographic functions! A quick trip to their API documentation pages reveals the purpose of their arguments.

Now we know:

private static byte[] a(boolean paramBoolean, byte[] paramArrayOfByte, String paramString)
{
    int i = cc.c;
    byte[] arrayOfByte1 = a(paramString);
    //First argument is the decryption/encryption key, second argument is the algorithm being used
    SecretKeySpec localSecretKeySpec = new SecretKeySpec(arrayOfByte1, z[1]);

    //Only argument is the algorithm being used
    Cipher localCipher = Cipher.getInstance(z[2]);

    //Only argument is the data for the initialization vector
    IvParameterSpec localIvParameterSpec = new IvParameterSpec(z[0].getBytes());

    //...
}

We are, however, lacking all values of “z”; these values are important as they’ll clearly tell us both the algorithm used for decryption and the initialization vector. They are not present in the decompiled code, so we’ll have to get them from the debugger. We also note “z” is a static class variable, and so we should be able to pick out said values any time. Given we’re interested how the decryption function works, we should breakpoint that and then we can start to kill two birds with one stone!

We can also now disable the watchpoint on “f.g” as we’ve found the method of interest. Restart the process and wait till you hit the breakpoint from logging in. (You’ll hit the breakpoint once when the program starts, but I have yet to figure out why).

Expressions let us inspect arbitrary parts of the program. It’s time to add one so we can find out the value of that mysterious “z”! Right click in the expressions pane and select “Add Watch Expression…”

And then enter the value “dc.z” as that is the variable we are interested in.

And then watch the magic!

This tells us some very important things! They’re just using plain old AES to encrypt their data and what the initialization vector is they use to encrypt it! So that’s one bird. Now for the other; we want to see how the function is actually used and what values are fed into it. If you go back to the variables tab you’ll see what the arguments to the function are. But things are not as they seem…

What on earth is the web username doing there?

this.l.g = dc.a(
    zc.f(), //we assume this returns encrypted data
    this.l.e //this is the SIP username, NOT the web username!! So what gives?
);

Well clearly “dc.a” is being called from somewhere other than just that line above or we’ve really messed things up; but to be safe we’ll hit “Continue” in the debugger and see if we can reach a point where “arg2″ is the value we expect, the SIP username (i.e. phone number).

Our patience is rewarded! Let’s go back and see how this plays out in our function.

 private static byte[] a(boolean paramBoolean, byte[] paramArrayOfByte, String paramString)
{
    int i = cc.c;

    //So this basically calls a("16042834338") and sets arrayOfByte1 to its value
    byte[] arrayOfByte1 = a(paramString);

    //This creates a new key using the output of the previous function for an "AES" cipher
    SecretKeySpec localSecretKeySpec = new SecretKeySpec(arrayOfByte1, z[1]);

    //Creates an "AES/CBC/NoPadding" cipher instance
    Cipher localCipher = Cipher.getInstance(z[2]);

    //Creates an initialization vector using the string "fedcba9876543210"
    IvParameterSpec localIvParameterSpec = new IvParameterSpec(z[0].getBytes());

The next part appears dependent on the boolean parameter. We need to know a little more about the “Cipher” object before we can determine what this function does. A quick trip to the API reference shows the first parameter determines the ciphers operating mode (encryption vs decryption for example), with the other arguments being self explanatory: the encryption key and the initialization vector. “arrayOfByte2″ appears to be the data which is either encrypted or decrypted.

    byte[] arrayOfByte2;
    if (i == 0)
    {
      if (paramBoolean) //false in our case
      {
        //initialize to encryption mode
        localCipher.init(1, localSecretKeySpec, localIvParameterSpec);

        //set the data to be encrypted via "md.a" using the third parameter of this function
        arrayOfByte2 = md.a(paramArrayOfByte);
        if (i == 0);
      }
      else //so we go here
      {
        //initialize to decryption mode
        localCipher.init(2, localSecretKeySpec, localIvParameterSpec);
      }
    }
    else
      //data to be processed is just the input
      arrayOfByte2 = paramArrayOfByte;

    //perform the encryption/decryption of arrayOfByte2
    byte[] arrayOfByte3 = localCipher.doFinal(arrayOfByte2);

    //return the processed data
    return arrayOfByte3;
  }

The “i” variable is a little confusing and it may be a side-affect of the decompiler not doing something right; from here on out we have to start making some educated guesses. We know the processing key is ALWAYS altered by some function, (ironically ALSO called “a”), we know one function does both encryption and decryption, we know that when the SIP username is involved as part of the key argument this function operates in decryption mode. It is likely safe to assume that the second parameter is therefore the encrypted SIP password.

I’m going to briefly force you to go back in time, to when the web username was present instead of the SIP username. Look at the first parameter; it’s true instead of false! This means that your web username is being used to encrypt something! This might be useful knowledge for later!

We’re getting really close now! We basically need to understand what the key modification function does.

byte[] arrayOfByte1 = a(paramString);

You will find its basic purpose is thus:

ec localec = new ec(paramString);
byte[] arrayOfByte = md.b(localec.a().substring(0, 16));
return arrayOfByte;

We’re now involving another TWO new classes! Egads! So we need to understand “ec” as well as the function “md.b”. Let’s deal with “ec” first by opening it up in the decompiler. The constructor is nothing interesting, it just saves the given key to a local variable. We’re interested in the “ec.a” function, which does nothing really but call “ec.b”. So let’s look at that.

It seems to involve message digests and another missing variable!

localMessageDigest = MessageDigest.getInstance(z[1]);

Not even looking I imagine just like how “AES” was selected as the crypto algorithm, “z[1]” represents the choice of message digest algorithm. What is “z[1]”? Remember how we found “dc.z”? You can use exactly the same trick to find “ec.z”. Add a method breakpoint to “b”, add a watch expression for “ec.z”, disable all your other breakpoints and restart the debugger. You’ll have your z in no time!

So we now know that MD5 is somehow involved in transforming the given crypto key. Not like MD5 and AES has ever been used before…

arrayOfByte = localMessageDigest.digest(this.a.getBytes());

Seems to perform the actual MD5 on the crypto key. We then observe what happens to the variable “arrayOfByte”. We see a loop and observe a lot of “Integer.toHexString(arrayOfByte[i]);” calls. The educated guess says that the returned MD5 hash is raw binary data and they are turning it into its hex form. However, we should attempt to verify this. We note at the very end:

return this.b;

They use b to store the result of the transform. We can simply add a watchpoint to “ec.b” and we’ll be able to test!

We know “ec.a” stores the plaintext value, so we just disable all other breakpoints, restart the program and compare! Remember, when the breakpoint hits, use “Step Over” so the value actually gets assigned. The first breakpoint you hit will likely be “b” being initialized to “null”, but the second… well that should be just magical.

And now we just check to make sure our hypothesis is correct:

echo -n "16042834338" | md5sum
b904785204cd684ff3965bc263220fc6

And it is! Fantastic! We now know “ec” is basically an MD5 hashing class. We go back to the line of code dealing with the transform and note that it appears to take only the resultant first 16 characters of the hex form of the MD5 hash and then pass those 16 characters into “md.b”.

md.b(localec.a().substring(0, 16));

So once again open up the decompiler and find the “md.b” that takes a single string as its argument. It seems to involve a bunch of checks, but its main purpose seems to revolve around the line:

arrayOfByte[i] = (byte)paramString.charAt(i);

It essentially seems to just convert a string into an array of bytes. Why they weren’t using String.toBytes() who knows. But to say the least that function doesn’t seem to bastardize anything about the crypto key.

With all this information it is hard to think that we are not done yet. We still don’t know how to get the encrypted password and we still need to test our ability to decrypt that password. We know the encrypted password is sent to us over the air, so we can at least start there. Disable all your breakpoints, restart the program and fire up WireShark.

NOTE: For your own good, turn off your torrents, streaming music and other things which obsessively fire packets off over your network. It will make your life MUCH easier trying to sift through things in WireShark.

With as little delay as possible start capturing packets and log into FreePhoneLine. As soon as you see yourself log in stop capturing packets and start to browse through the dump looking for things related to FreePhoneLine. One quickly finds that the authentication happens over HTTP and that the typical response looks something like:

One can make an educated guess that the encrypted password is base-64 encoded, simply by seeing the “==” on the end and knowing that encrypted data almost always falls outside the printable ASCII range.

So let’s build a program to decrypt these passwords! I’m going to use (yea haters gonna hate) PHP because it comes with cryptography functions built in and is fast to prototype things with.

<?php

function new_freephoneline_crypto_context($Key) {
	$Key = substr(md5($Key), 0, 16); //The first 16 characters of the hex represntation of the MD5 of the key
	$IV = 'fedcba9876543210'; //The IV they use
	if ($CryptoModule = mcrypt_module_open('rijndael-128', '', 'cbc', '')) { //Open the cipher (AES _is_ Rijindael)
		mcrypt_generic_init($CryptoModule, $Key, $IV); //Initialize
		return $CryptoModule; //Return
	} else {
		die('Initializing mcrypt failed!');
	}
}

function delete_freephoneline_crypto_context($CryptoModule) {
	mcrypt_generic_deinit($CryptoModule);
	mcrypt_module_close($CryptoModule);
}

$SIPUsername = '16042834338';
$EncryptedSIPPassword = base64_decode('WhubSHQz2nqFNK/N0xGMvw==');

$Context = new_freephoneline_crypto_context($SIPUsername);
$DecryptedPassword = mdecrypt_generic($Context, $EncryptedSIPPassword);
delete_freephoneline_crypto_context($Context);

$Output = 'Username is: '.$SIPUsername.', and password is: '.$DecryptedPassword;

echo $Output;
?>

Funny thing is, it works. You can now successfully take any of their encrypted SIP passwords and derive their plaintext ones. But we’re not done yet. So far we still need to use WireShark to get at those encrypted passwords. We want a truly automated process. We need to know how FreePhoneLine requests that information as well. You can easily find it in WireShark.

Le sigh. It looks like they encrypt the web password going out as well, and we’re going to have to mimic that. But wait… don’t you remember that one time we saw the debugger stop and use our web username as a key for ENCRYPTION? It’s starting to come together now isn’t it? We can make another educated guess in that it simply encrypts our web password with our web username in the exact same manner it decrypts the SIP one. We can write another program to test this!

This is also a bit of a crapshoot, as I have no idea how “key” is generated, or even if its necessary. But after some testing it turned out that not providing “key” doesn’t make any difference.

<?php

$WebUsername = 'izaak.schroeder@gmail.com';
$WebPassword = 'lolfreephoneline';

$Context = new_freephoneline_crypto_context($WebUsername);
$EncryptedWebPassword = mcrypt_generic($Context, $WebPassword);
delete_freephoneline_crypto_context($Context);

if ($CURLHandle = curl_init('http://www.freephoneline.ca/services/init')) {
	curl_setopt($CURLHandle, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($CURLHandle, CURLOPT_HEADER, false);
	curl_setopt($CURLHandle, CURLOPT_POST, true);
	curl_setopt($CURLHandle, CURLOPT_POSTFIELDS, ''
		.'web_username='.urlencode($WebUsername).'&'
		.'web_password='.urlencode(base64_encode($EncryptedWebPassword)).'&'
		.'key='
	);

	$Data = array();
	foreach(explode("\r\n", curl_exec($CURLHandle)) as $Line)
		if (false !== $Target = strpos($Line, '='))
			$Data[trim(substr($Line,0,$Target))] = trim(substr($Line, $Target+1));
	curl_close($CURLHandle);
	echo 'SIP username: '.$Data['sip_username'].', encrypted SIP password: '.$Data['sip_password'];
} else {
	die('Initializing CURL failed!');
}
?>

Oh look, it works! We have effectively and nearly completely (save for whatever “key” does) emulated the FreePhoneLine authentication protocol. Combining those two scripts might leave you with something like:

<?php

//This file is called ffd.php

$Output = 'Nothing interesting to show here Capt\'n';

function new_freephoneline_crypto_context($Key) {
	$Key = substr(md5($Key), 0, 16);
	$IV = 'fedcba9876543210';
	if ($CryptoModule = mcrypt_module_open('rijndael-128', '', 'cbc', '')) {
		mcrypt_generic_init($CryptoModule, $Key, $IV);
		return $CryptoModule;
	} else {
		die('Initializing mcrypt failed!');
	}
}

function delete_freephoneline_crypto_context($CryptoModule) {
	mcrypt_generic_deinit($CryptoModule);
	mcrypt_module_close($CryptoModule);
}

if (isset($_REQUEST['u']) && isset($_REQUEST['p'])) {

	$WebUsername = $_REQUEST['u']; $WebPassword = $_REQUEST['p'];

	$Context = new_freephoneline_crypto_context($WebUsername);
	$EncryptedWebPassword = mcrypt_generic($Context, $WebPassword);
	delete_freephoneline_crypto_context($Context);

	if ($CURLHandle = curl_init('http://www.freephoneline.ca/services/init')) {
		curl_setopt($CURLHandle, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($CURLHandle, CURLOPT_HEADER, false);
		curl_setopt($CURLHandle, CURLOPT_POST, true);
		curl_setopt($CURLHandle, CURLOPT_POSTFIELDS, ''
			.'web_username='.urlencode($WebUsername).'&'
			.'web_password='.urlencode(base64_encode($EncryptedWebPassword)).'&'
			.'key='
		);

		$Data = array();
		foreach(explode("\r\n", curl_exec($CURLHandle)) as $Line)
			if (false !== $Target = strpos($Line, '='))
				$Data[trim(substr($Line,0,$Target))] = trim(substr($Line, $Target+1));
		curl_close($CURLHandle);

		if (!isset($Data['sip_username']) || !isset($Data['sip_password'])) {
			$Output = 'Error getting credentials; perhaps wrong username or password?)';
		} else {
			$SIPUsername = $Data['sip_username'];
			$EncryptedSIPPassword = base64_decode($Data['sip_password']);

			$Context = new_freephoneline_crypto_context($SIPUsername);
			$DecryptedPassword = mdecrypt_generic($Context, $EncryptedSIPPassword);
			delete_freephoneline_crypto_context($Context);

			$Output = 'Username is: '.$SIPUsername.', and password is: '.$DecryptedPassword;
		}
	} else {
		die('Initializing CURL failed!');
	}
}
?><html>
	<head>
		<title>Freephoneline SIP Credentials Decryptor</title>
	</head>
	<body>
		<form method="post" action="ffd.php">
			<fieldset>
				<legend>FreePhoneLine Login Information</legend>
				<div>
					<label>Username:</label>
					<input style="width: 200px;" type="text" name="u" placeholder="username" value="<?php echo isset($_REQUEST['u']) ? $_REQUEST['u'] : '' ; ?>"/>
				</div>
				<div>
					<label>Password:</label>
					<input style="width: 200px;" type="password" name="p" placeholder="password" value="<?php echo isset($_REQUEST['p']) ? $_REQUEST['p'] : ''; ?>"/>
				</div>
			</div>
			<div><input type="submit" value="Get My SIP Info"/></div>
		</form>
		<hr/> <?php echo $Output; ?>
	</body>
</html>

After such a long journey seeing something like:

is immensely satisfying, isn’t it Tom?

And what about that security hole I mentioned? Well thing is, they encrypt your web password with your web username… both of which are sent in plaintext over the wire. You can already see how dumb of an idea this is. If someone is using FreePhoneLine on your network and you have WireShark going and you get their encrypted web password and their login… guess what! You have their decrypted web password too!

Anyway, hope you’ve enjoyed this little adventure. And remember kids, only you can prevent bad designs from being used!

Until next time!

Reverse Engineering Java; or How to get a free Canadian DID

So I was asked to create a component for a support application that automatically pulls in customer information when said customer calls in to receive support. It makes life easier for the agent (they get pertinent info quicker) and makes life easier for the customer (they don’t have to spend time giving the agent information). That way you don’t get this:

Though anyone whose called Telus’ tech support knows that’s the least of their problems.

Anyway, writing this little script involved making use of the AGI (an API) in Asterisk (free PBX software). So like any good developer I read the API specification, installed Asterisk and wrote some code to handle incoming calls. But I pondered how I would test this beast; I didn’t wanna throw it up on a production server (we all know what happens when we publish untested code right guys?)… but then I remembered a good friend of mine, Alex, had recently told me about this free DID he’d gotten. Perfect! Except his free DID was from Washington and I didn’t want to be calling long distance. What do?

A quick trip to Google provided me with a solution to said problem; this amazing site: http://www.freephoneline.ca. A free Canadian DID in Vancouver, with unlimited incoming and local outgoing; too good to be true, right? And it almost was. Which is why this article is here. That little bit of “almost” was solved with a little bit of reverse engineering sorcery.

When you sign up you’ll be asked for a username (your email) and a password. Nothing unusual here. Then you must download their soft-phone client to interact with their SIP gateway. Their softphone requests your email/password combination you used to signup; trying to pass this as a SIP username and password in another VOIP client (Asterisk, other softphones, etc.), however, will get you nowhere.

A trip to their website told me I could pay them $50 so they could send me a config file with the SIP information in it. Except I knew in order for their softphone to work that same $50 worth of information existed in my computer absolutely free. Their site is “FREEphoneline.ca” after all.

Like any curious mind you can simply open up Wireshark and check out all the SIP traffic that’s heading out to their server. As it turns out your email/password combination is used to retrieve your SIP username/password; unfortunately one quickly comes to the conclusion that this information is encrypted and therefore not immediately useable. But, since the softphone obviously uses it to authenticate with their SIP service, the ability to decrypt those credentials must be present in the softphone software! And thus we begin our foray into abusing the softphone until it begs for mercy and yields us our SIP password.

Their softphone is called “FreePhoneLine”. If we take a quick peek into the program’s folder we notice that there is a “FreePhoneLine.jar” file. Add that to the fact they advertise it running on both Mac OS X and Windows, we can safely assume that this is a Java program.

Cool thing about Java “JAR” files: they’re just zip files. So let’s start digging into this program. Decompress “FreePhoneLine.jar”. (7zip will do this rather nicely). Ugh. All the Java class files are there but they all have names like “a”, “ab”, “b”, “c” and so on. Looks like someone ran this guy through an obfuscator to make our work a little bit more difficult. We can use tools like Ollydbg or IDA to inspect memory and DLLs that this program uses, but they are both primarily x86 debuggers; we need a program to debug Java opcodes, and what better one to use than Eclipse.

Load up Eclipse, create a new Java project and name it whatever you feel like.

Click “Add External Class Folder” and select the folder you just decompressed the JAR into. Next, click “Add External JARs” and go into the “FreePhoneLine/lib” folder and add all the JARs in there. Finish making the project.

Now, we need to find the class with the “main” function in order to start it running. Thankfully, JARs contain this nice little “META-INF/MANIFEST.MF” file which tells us which class has “main” in it. Open up the “MANAFEST.MF” file and you’ll see “Main-Class: vonix.ua.MainWnd”. How simple! In Eclipse open up the “vonix.ua” package, browse down to “MainWnd”, right click and select “Debug”.

So now that we’ve this program running, let’s actually go abuse it! Fill in your login information but don’t hit the login button. This next part is a little bit of a gamble. We know that the softphone retrieves your SIP credentials and then decrypts them and then connects the softphone to their SIP service. We’re going to make the gamble that if we hit login and pause the program in the debugger quick enough, there’s going to be some object still floating around with our SIP credentials.

With a little bit of probing it looks like we’ve hit the jackpot! There’s class named “kc” that contains the server information as well as the SIP username and decrypted password (found in the field “g”)! Copy that password somewhere and you basically have SIP credentials for a free DID with unlimited incoming and local outgoing calls.

If you want to keep probing for passwords, simply add a function breakpoint to the “kc” class’ constructor. That way you don’t need to make gambles about when you should stop the debugger; every time a decrypted password is passed into “kc”, Eclipse will pause the program and show you it.

Awesome? I think so.

And remember kids: security by obscurity never works. Ever. With perhaps one exception: you find a way to completely blackbox your code. This is the trusted client problem. If FreePhoneLine wants to fix up this wonderful little hole they need to assume their code can and will be introspected.

There is no real solution when you offer free service based on a standard protocol, but want to restrict it based on code running on the client’s machine! You cannot trust clients.  Anything that needs trust should be happening on the server. It’s a more sophisticated equivalent of those sites that try and force you to view them using Internet Explorer via the “User-Agent” header.

As an added bonus I’ll throw in the Asterisk config so you can get this bad boy rolling on your very own free phone server.

; /etc/asterisk/sip.conf

[general]
useragent=FreePhoneLine 2.2.3.0 ; not sure if this is needed but it can't hurt
register => YOURPHONENUMBER:YOURPASSWORD@voip.freephoneline.ca:5060

[incoming]
type=friend
context=incoming
username=YOURPHONENUMBER ; e.g. 16041234567
secret=YOURPASSWORD ; eg 4RswqQ3
fromuser=YOURPHONENUMBER
qualify=no
insecure=port,invite
canreinvite=no
allow=ulaw ; you might be able to get away with other codecs in here
host=voip.freephoneline.ca
port=5060
realm=208.65.240.142 ; the IP address of voip.freephoneline.ca, not sure if this is needed though

As an exercise to the reader, you could have some extra fun and trace up the call stack from kc’s constructor and find the actual method that decrypts the password. From there on you could just decompile (ah the advantages of reverse engineering Java) the method block and create your own Java program to decrypt these passwords. Much easier than having to load the Eclipse debugger every time!

Introduction to an Arcane Art: Parsing

Foreword: I know this is a simplified version of what really constitutes parsing; that there are other kinds of parsers and whole other classes of grammars that this kind of parser cannot deal with. And that’s ok. This isn’t an article about the theory behind it all. This is a practical introduction.

Parsing is one of those things that, for the average folk, isn’t really well understood or well defined. People seem to get the idea that it’s the component responsible for understanding data you feed a program. So let’s see what happens!

It’s a magic box that takes your input and constructs the ever-so-mythical parse tree. This tree is the materialization of the role the parser fulfills: a little something called syntactical analysis. Syntax deals with the structure and rules of input. Things like saying: “a statement MUST be followed by a semicolon” is part of those rules.

If we look at the input:

{
    int f;
    f = 5 + 3;
}

We might get the following parse tree:

All the bottom-most nodes (i.e. the nodes without any children) are called the “tokens” and all the nodes circled in red are called “non-terminals”. It’s the non-terminals that give the input its structure, or syntax. You can see that, with relative ease, this program can be evaluated by going upwards in the tree from the bottom, left-to-right. (Known as a depth-first transversal). So now let’s talk a bit about these tokens.

The parser’s best friend is the lexer (also known as the tokenizer). I won’t go over it in too much detail, except to say that it performs the complementary job of breaking up the input into tokens: the smallest unit of meaningful information.

You might think of this as a classification, or generalization process. The parser deals only with the structure of the input, so it is concerned with where pronouns are allowed to go, where verbs are allowed to go, and so on; not which part of the input actually makes up a word and what kind of words they are.

The parser then takes that input and also does a form of generalization called a “reduction”. The input is continuously shifted onto a stack until some useful generalization can be made about the contents of the stack. This process of generalizing is called reducing because you reduce some input to another, more concise form.

We continue to shift the input onto the stack until we notice that we can represent the data on the stack in a more concise manner!

“int f;” represents a variable declaration! So we can simplify the stack!

The shifting continues until we have:

“3+5″ can be reduced to an “expression”. (In this case an expression is anything that generates a value).

This process repeats itself until all of the input has been consumed and reduced to a single statement or the parser is given a token it knows it can’t make use of in ANY reduction and it tells you there’s been a parsing error! And there you have it: a shift/reduce parser in its most basic form.

The most important part of parsing is the process of reducing. The reductions classify the input into more and more general forms and determine where, precisely, in the structure everything fits. So we now  have this cool shift/reduce thingy, how do we get it to produce that fancy little tree? The answer is terribly simple.

Every time there is a reduction, you create a new node in the tree. That new node has, as its children, all the nodes that were involved in the reduction.

So then it begs the question how do we know when to reduce and when to shift? Unfortunately that answer is a lot more tricky, especially when you have many rules regarding how your input is structured. Most of these parsers work by using something called a “lookahead”. The lookahead is a certain number of tokens that the parser examines (in combination with the contents of the stack) to determine its next action.

The number of tokens used in the lookahead is usually represented by the constant “k”. Most programming languages (e.g. Java, C) can be parsed with k=1, though there are some notable exceptions like C++ which cannot be parsed for ANY k. And you’re thinking: what does this even mean and why do I care?

It means no matter how far you look ahead in the input, you won’t be able to decide whether to shift a certain symbol, or to reduce. What does one do then? Do what any indecisive fool does and try both! Every time you’re not sure what to do, you can split the stack and perform one action on one stack, and the other action on the other stack. You continue feeding input to all stacks until all but one of them produces an error, leaving you with the correct interpretation of the input.

And there you have it. That’s how the magic box works!

Tagged

Saturday Night’s Alright for Reverse Engineering

Arguably one of the most complicated processes in computing is modifying a program that you don’t have the source code to. Why on Earth would you ever want to do this? Because you like figuring out how things work of course, and you don’t feel like having to put the CD in every time you play your favorite game.

Now before I get right into the article I want to address all the business bigwigs that are going to throw DMCA hissy-fits.

That’s what it boils down to right? And you want people paying for your game.  Why do people buy games? Because they’re worth playing, because they provide an engaging experience. Here’s been the experiences I’ve been hearing about:

And you want to know what pirates have to say to all your DRM trickery?

Absolutely nothing. They just know they’re better than you at making users’ lives easier. And they’ll keep on proving it.

Name me one game that hasn’t been broken. Oh wait, that’s right. You can’t. What you can do is provide people awesome experiences they can’t get without paying for your game. This involves being convenient; this involves being online. Call of Duty: Modern Warfare 2 has it down to a science. Keep the dedicated servers to themselves. This makes pirating virtually impossible and even if someone went and reverse engineered a server (which is possible) its user base would be small enough to not be convenient for players to want to use.

Get smart. Do yourself a favor and don’t make life painful for your users.

On top of that I’d like to make the argument requiring the CD is an inconvenience, not a copy protection scheme. Why? Any average Joe can go use PowerISO, DaemonTools or any other virtual CD drive tool to achieve the same effect this article produces. And they can do so without touching a line of code!

But we’re code ninjas, and that just isn’t fun! Rant aside, let’s begin!

Now I’m going to be doing this demo using “OllyDbg”. It’s free and getting your copy is easy. Click here. There are other, more advanced tools for doing binary analysis and reverse engineering like IDA Pro, but such programs are also very costly. They find their way into virus research labs and other places that are up against very heavy binary protection and obsfunctuation.

Remember: When you’re doing any work that involves modifying programs, make backups.

So I’m going to be removing the CD requirement for Dragon Age. This game is fantastic for a single-player RPG; and this is coming from someone who generally never plays single-player games, ever. Even the Zero Punctuation guy seemed to like it. So to begin, fire up Dragon Age without the CD. You should end up seeing this friendly message:

Who honestly wants to bother trying to find the CD every time? Those crafty jews at BioWare have basically done this:

if ( cd_is_present() ) load_game();
else show_lame_error("The CD is not in the drive lol kthxbai");

And we know if statements turn into conditional jumps. Generally these are either “jnz”, “jz”, “jne”, or “je” for booleans. (Jump if not zero, jump if zero, jump if not equal and jump if equal). All we do is change these to either a “jmp” or “nop” instruction, effectively either always taking or never taking the jump. The hardest part is finding the specific jump that does the actual CD checking. Fortunately OllyDbg has some tools that will help us find what we need.

In order to find the jump, we can narrow our search a lot just by finding the code section it’s in. We know that a particular error message is displayed, so we can open OllyDbg’s “Memory Map” and search for the string. We also note it is possible to play Dragon Age in several languages, so an initial assumption that the string is unicode is reasonably valid. (We can of course change to ASCII if our search fails).

Oh looky here.

Perfect. Now we need to know when that particular spot in memory is accessed. To achieve this we can use a hardware breakpoint. (Software breakpoints are generally used for breaking on instructions, as opposed to data).

Running the program again results in the the hardware breakpoint being hit and returning execution back to OllyDbg. We end up with a call stack like this, somewhere deep in the message box function used to present the message. If we follow the stack downwards we can view all the function calls leading up to this one.

And here’s what we’re looking for: the function in Dragon Age that called the message box creation function.

So we can inspect that and try and find the offending jump call and turn off our hardware breakpoint.

So we set breakpoints on each of the jump calls and run Dragon Age again. Each time we hit a breakpoint check out this little bit of status information.

We want to invert that call and make it so the jump isn’t taken. Since we don’t know what effect this will have on our program, it’s easiest just to use OllyDbg’s “New Origin Here” command which modifies EIP to point to the presently selected instruction. After we do that we resume the program to see what effect it has.

A different error message! Looks like progress to me. I’m going to make an educated guess and assume that we’ve convinced it a disk is in the drive, but its failing checking some signature on the disk. (Namely because there is no disk). So let’s do the same thing with the next breakpoint.

Remember: You need to “New Origin Here” every time you debug!

This time it looks like the second jump isn’t taken. Using OllyDbg we can see where that jump is going, and use “New Origin Here” again.

Now we resume the program.

What’s that? Dragon Age is now running without the CD? Cool story bro! Now we just need to make the patch permanent. In cases we want to force a jump NOT to be taken, we use the “nop” instruction. In cases we want to force the jump we use the “jmp” instruction. The “nop”  instruction is easy, and consists of merely the byte “0x90″. Let’s apply that to the first jump.

OllyDbg has a function called “Fill with NOPs” which works perfectly for this.

The next jump needs to always be taken. The short “always jump” instruction is “0xEB”. Open the “Binary Edit” window and change the conditional jump “0x74″ to always jump “0xEB”. Leave the value beside it alone. This just tells the computer how far it needs to jump. This makes the patch permanent in OllyDbg.

Now after all that we’re done! We can run our favorite game without having to go dig up the CD every time we want to play it. As a final note after reading this article; if this is you:

Please go kill yourself now.

Code Thunking For Fun and Profit

This article is somewhat incomplete, but you can get an idea of what’ll be posted here.

So this awesome question: “How do I take over other functions in C++?” was submitted. It’s awesome because it involves hijacking, domination and lots of coding trickery. Read on to find out more!

If you’re a code ninja like me and you have problems with existing programs not doing what you want (and the developer is a lazy ass and won’t implement your feature), this is for you! This article is written with a C/Windows spin to it, but it’s relatively portable.

Anyway, the basic principal works something like this:

Except in our case the drugs will be a DLL containing whatever other feature we want to implement and the injection will be done by making a codecave.

My latest addiction is this game:

And while I’m constantly getting hat-tricks and causing 13-year old boys to yell and scream like the prepubescent tools they are, nothing says “I will ravage your anus” quite like actual video footage.

Heroes of Newerth does not, unfortunately, come with a video capture feature. But what about FRAPS you ask?! You’re a code ninja; you don’t use other peoples crappy software; you use your mad skills to solve your problems. Or, in this case, my mad skills.

Now, Heroes of Newerth uses the K2 Engine which, on Windows, uses Direct3D to do all its rendering. This is a bit of a shame because D3D is like OpenGL’s retarded brother.

So let’s get starting hooking stuff! We need to delve a little into compiler and assembly land here. (Yea, don’t give me that look). Every function call, i.e.

foo();

you make usually winds down to looking like this in machine code (hex):

E9 XX XX XX XX

Riveting, I know. It instructs the CPU to run the code at the XX XX XX XX bytes from the current location. So in theory, we could find out every spot where “foo” is called and replace the offset with something pointing to our own function. That scenario looks like this:

You’re one of those kids that can count to potato right? Instead, a better approach is to modify “foo” itself. After all, all the calls to “foo” point to some spot in memory, so we can just take that spot and put the code we want to run in it right?

Unfortunately, you can’t fit 10 pounds of code into a 5 pound bag. So we’ll just detour the code instead. We’ll overwrite the first few bytes of the function to jump to some other spot in our code. That solves both problems neatly. Or, almost.

The only problem we get is that if we want to use the old function again, we’re going to need to do some patchwork as we basically removed part of that function in order to make our detour call.

Complicating things on top of all this is the X86 architecture itself. Instructions come in various sizes! So when we cut out part of the original function, we want to make a clean cut and not slice in the middle of an instruction.

Cutting in random locations generally results in blood flying everywhere and programs crashing because they have no idea what’s going on. Our specialist in dissecting code will be a “dissembler”. It will be able to tell us what boundaries are safe to cut on (i.e. those which are whole instructions).

I’ve chosen to use XDE because it’s small, written in portable C and has a big enough feature set for what we’re doing. Feel free to pimp your code and use whatever dissembler you want.

So as an overview for those of you that have survived this far:

  1. Find target function memory address.
  2. Dissemble the first several bytes and find instruction boundaries.
  3. Copy to temporary storage at least 5 bytes and stop on an instruction boundary.
  4. Overwrite the first 5 bytes with a function call to our function.

This will give us enough to replace the function with our function (and optionally restore it later). This will NOT let our new function call the old one. But calling the old one can be done with a little trickery! Remember we saved that hunk of the original function? We just need to add a jump instruction at the bottom of it to continue where we left off after the slice.

And there you have it. Hooking with the old function still available. This pretty much answers the reader’s question, but we’ll go and make it go cool stuff now.

As an aside, if you’re doing this kind of hooking to real applications, tools like PunkBuster and Kaspersky like to throw a giant hissy fit because you’re making programs do things they’re not supposed to! (Like cheating or stealing keystrokes… but of course you wouldn’t do that!).

Unless things have changed, both of those programs tend to check the first byte of a function to see if it’s “e9″. (i.e. “Derp someone’s patched this function with a jump call”). Well we can obviously be a lot smarter than that using our dissembler. We can easily place our jump call one or two instructions down assuming some basic criterion are met (stack preservation mostly). Unfortunately I’m just taunting you and am not actually going to show you how to do that in this article. Try it though, really, it’s lots of fun.

Now that we can hook functions, we need to override a Direct3D call or two. Because we’re dealing with COM it means every object has a pointer to its own vtable (much like C++). Which means we need to hook the function that creates the object’s whose methods we want to hook. Messy but you can go send hatemail to Microsoft if you want.

We need to hook:
Direct3DCreate9 and Direct3DCreate9Ex
In order to hook the vtable for the Direct3D manager we get back.

LPDIRECT3DRM lpD3DRM;
Direct3DRMCreate(&lpD3DRM);
lpD3DRM->lpVtbl->Present; // That's the function we ACTUALLY want to hook

But before we do that we need to write both the function that’s going to be replacing it and a function that starts and stops the recording. We’ll do the one that starts and stops recording first because it’s easy. On Windows we have event hooks provided by the Windows API, (vs using our crafty hooking method), that we can use!

So after setting up our D3D hooks we also install our keyboard hook. All it will do is check to see if the user hit the F11 key and if so toggle recording. Naturally you can make this whatever key you want but no one ever seems to use F11 for anything.


void InitializeAwesomeLibrary()
{
    //Other init stuff here
    ...
    //Remember to the read the API docs on this kids otherwise you might end up hooking every
    //program in the system (re crappy keylogger)
    SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, GetCurrentThreadId());
}

LRESULT __declspec(dllexport)__stdcall  CALLBACK KeyboardProc(int Code, WPARAM wParam, LPARAM lParam)
{
    if (HC_ACTION == Code && wParam == VK_F11) //key was pressed and it's f11
        ToggleRecording(); //Change recording state
}

Mostly it’s just going to grab the pixels off the current Direct3D context, send them to a video library for encoding and call the old function again.

Now as much as Direct3D is a platform-specific piece of trash, FFMPEG is awesome. It shall be used to do my video processing. Make sure your copy of FFMPEG has x264 enabled: nothing says anal carnage like an HD version of you tearing the other team a whole new asshole.

//This baby is called instead of the real present
void HookedPresent()
{
    clock_t currentTicks = clock(); //get current tickets
    if (IsRecording && current - lastFrameTakenAt >= CLOCKS_PER_SEC / fps) //We need to take a frame
    {
        GetBackBuffer( 0, 0, Mono );
        avcodec_encode_video(c, outbuf, outbuf_size, picture);
        lastFrameTakenAt = currentTicks;
    }
    
    OldPresent(); //Call the old function to draw stuff on the screen
}

And now you can go make the next great version of FRAPS.

Follow

Get every new post delivered to your Inbox.