<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:ParamHandlers="ParamHandlers.*" width="537" height="595">
<fx:Script>
<![CDATA[
/****************************************************************************
* ADOBE SYSTEMS INCORPORATED
* Copyright 2012 Adobe Systems Incorporated and it’s licensors
* All Rights Reserved.
*
* NOTICE: Adobe permits you to use, modify, and distribute this file
* in accordance with the terms of the license agreement accompanying it.
* ****************************************************************************/
import Fuzzer.FuzzerDB;
import Fuzzer.FuzzerLogger;
import LCReceiver.LCReceiver;
import LCReceiver.LCReceiverEvent;
import ParamHandlers.ObjectParser;
import ParamHandlers.ParamCollection;
import mx.collections.ArrayCollection;
import mx.utils.ObjectUtil;
[Bindable]
private var varTypes:ArrayCollection = new ArrayCollection(
[ {label:"String", data:"String"},
{label:"int", data:"int"},
{label:"Number", data:"Number"},
{label:"Array", data:"Array"},
{label:"null", data:"null"} ]);
/**
* @private
* The last Args received by the LocalConnection
*/
private var lastArgsReceived:Array;
/**
* @private
* The fuzzer database
*/
[Bindable]
[Embed(source="assets/fuzzer/ErrorImage.jpg")]
public var errorIcon:Class;
private var fuzzLog:FuzzerLogger;
private var fuzzDB:FuzzerDB = new FuzzerDB();
private var currentSlot:int = 0;
private var currentName:String;
private var currentType:String;
private var currentFuzzValue:String;
private var defaultParams:Array;
private var rawParams:Array;
private var lastNavPos:int;
/**
* @private
* The callback function for the LocalConnection to send feedback to the user regarding a success or failure.
*
* @param event The LocalConnection StatusEvent
*/
private function onSendStatus(event:StatusEvent):void {
switch (event.level) {
case "status":
this.sendStatus.text = "LocalConnection.send() succeeded";
break;
case "error":
this.sendStatus.text = "LocalConnection.send() failed";
break;
default :
this.sendStatus.text = event.level + ": " + event.code;
}
}
/**
* @private
* Collect the data and send it across the LocalConnection.
*/
private function sendData():void {
var args:Array = new Array();
args.push(this.targetConnection.text);
args.push(this.targetFunction.text);
var temp:Array = this.sendDG.getFuncParams();
for each (var val:* in temp) {
args.push(val);
}
var sLC:LocalConnection = new LocalConnection();
sLC.addEventListener(StatusEvent.STATUS, onSendStatus);
sLC.send.apply(this,args);
sLC.close();
}
/**
* @private
* Receives information from the LocalConnection and dumps it to the outputData text field.
*
* @param e The LCReceiverEvent fired when data comes in.
*/
private function receiveEvent(e:LCReceiverEvent):void {
var outputData:String = "";
//Trying ObjectUtil for short time due to bug in arrayToString with nested arrays
//var oParser:ObjectParser = new ObjectParser();
//outputData += oParser.arrayToString(e.args);
outputData += ObjectUtil.toString(e.args);
this.lastArgsReceived = e.args;
this.rOutput.text = outputData;
}
/**
* @private
* Recieves a LocalConnection Status Update from the LCReceiver class and updates the status field.
*
* Not sure it ever catches anything.
*
* @param e The LCRecieverEvent for the status update.
*/
private function rStatusUpdate(e:LCReceiverEvent):void {
this.receiveStatus.text = e.status;
}
/**
* @private
* Registers a LocalConnection Receiver useing the LCReceiver Class and the information from the tab.
*/
private function receiveFunction():void {
if (this.connectionName.text == "" || this.functionName.text == "") {
return;
}
var lcReceiver:LCReceiver = new LCReceiver(this.allowDomain.text);
lcReceiver.connect(this.connectionName.text);
lcReceiver.addEventListener(LCReceiverEvent.STATUS_RETURNED,rStatusUpdate);
lcReceiver.addEventListener(LCReceiverEvent.CONNECTION_RETURNED,receiveEvent);
lcReceiver[this.functionName.text] = function (... args):void {fscommand('foo',args[0]);lcReceiver.bubbleArgs(args);};
this.receiveStatus.text = "Function " + this.functionName.text + " added to " + this.connectionName.text;
this.connectionName.text = "";
this.functionName.text = "";
this.allowDomain.text = "";
}
/**
* @private
* Load XML from text field.
*/
private function addFuzzValues():void {
if (fuzzXML.text.length == 0) {
sendStatus.text = "No values provided in text box";
}
try {
this.fuzzDB = new FuzzerDB(new XML(fuzzXML.text));
this.fuzzStatus.text = "";
} catch (e:Error) {
fuzzStatus.text = "Error Parsing XML" + e.message;
}
}
/**
* @private
* Sends the received Array to the Flash Analyzer Object Editor
*/
private function sendToOE():void {
var tempLC:LocalConnection = new LocalConnection();
tempLC.send("app#SWFInvestigator:objectEditor","editObject",this.lastArgsReceived);
}
/**
* @private
* Results the fuzzer to the default values
*/
private function resetToDefaults():void {
this.fuzzDB.setDefaults();
}
/**
* @private
* Clears default values
*/
private function clearDefaults():void {
this.fuzzDB.clearDefaults();
}
/**
* @private
* This function drives the fuzzing effort
*/
private function fuzzNext():void {
var tempParams:Array = this.fuzzDB.getNextAttackArgs(this.currentType,this.currentSlot,this.defaultParams);
if (tempParams == null) {
this.currentSlot++;
while (this.currentSlot < this.defaultParams.length && this.rawParams[this.currentSlot].fuzz == "n") {
this.currentSlot++;
}
if (this.currentSlot == this.defaultParams.length) {
this.fuzzLog.createCollection();
this.fuzzStatus.text = "Fuzzing Complete!";
this.winTN.selectedIndex = 3;
return;
} else {
this.currentType = this.rawParams[this.currentSlot].type;
tempParams = this.fuzzDB.getNextAttackArgs(this.currentType,this.currentSlot,this.defaultParams);
this.currentName = this.currentSlot.toString() + " - " + this.currentType;
this.fuzzLog.addSlotEntry(this.currentName, this.currentType);
}
}
if (tempParams[this.currentSlot] != null) {
this.currentFuzzValue = tempParams[this.currentSlot].toString();
} else {
this.currentFuzzValue = "null";
}
sendMaliciousData(tempParams);
}
/**
* @private
* Starts the fuzzing process
*/
private function sendMaliciousData(params:Array = null):void {
var args:Array = new Array();
args.push(this.victimConnection.text);
args.push(this.victimFunction.text);
if (params == null) {
params = this.fuzzDG.getFuncParams();
this.defaultParams = params;
this.rawParams = this.fuzzDG.getRawParams();
this.fuzzLog = new FuzzerLogger();
this.currentName = "baseline";
this.currentSlot = 0;
this.currentFuzzValue = "baseline";
if (this.rawParams.length > 0 ) {
this.currentType = this.rawParams[0].type;
}
}
if (params.length == 0) {
this.fuzzStatus.text = "You can't fuzz something that doesn't take arguments";
return;
}
for each (var val:* in params) {
args.push(val);
}
var sLC:LocalConnection = new LocalConnection();
sLC.addEventListener(StatusEvent.STATUS, onFuzzStatus);
sLC.send.apply(this,args);
sLC.close();
}
/**
* @private
* The callback function for the LocalConnection to send feedback to the user regarding a success or failure.
*
* @param event The LocalConnection StatusEvent
*/
private function onFuzzStatus(event:StatusEvent):void {
var resStr:String;
switch (event.level) {
case "status":
resStr = "LocalConnection.send() succeeded";
this.fuzzLog.addResult(this.currentName, this.currentFuzzValue,resStr);
break;
case "error":
resStr = "LocalConnection.send() failed";
this.fuzzLog.addResult(this.currentName, this.currentFuzzValue,resStr,"errorIcon");
break;
default :
resStr = event.level + ": " + event.code;
this.fuzzLog.addResult(this.currentName, this.currentFuzzValue,resStr,"errorIcon");
}
if (this.currentName == "baseline") {
while (this.currentSlot < this.defaultParams.length && this.rawParams[this.currentSlot].fuzz == "n") {
this.currentSlot++;
}
if (this.currentSlot == this.defaultParams.length) {
this.fuzzLog.createCollection();
mx.controls.Alert.show("Fuzzing Complete!","Success",4,this);
this.winTN.selectedIndex = 3;
return;
}
this.currentType = this.rawParams[this.currentSlot].type;
this.currentName = this.currentSlot.toString() + " - " + this.currentType;
this.fuzzLog.addSlotEntry(this.currentName, this.currentType);
}
fuzzNext();
}
/**
* @private
* Called by the AS3Navigator when someone selects an item in the tree, it decides what to put in the resultOutput box based on the selection.
*
* @param evt The tree selection event.
*/
private function treeSelect(evt:Event):void {
var node:XML = Tree(evt.target).selectedItem as XML;
if (node.@type.indexOf("slot") == 0) {
this.resultOutput.text = '';
} else if (node.@type.indexOf("result") == 0) {
this.resultOutput.text = node.@data.toString();
}
}
/**
* @private
* Initializes the Navigator tab on view.
*/
private function initNavigator():void {
if (this.fuzzLog != null) {
this.resultTree.dataProvider = this.fuzzLog.logData;
this.resultTree.labelFunction = this.fuzzLog.logTreeLabel;
this.resultOutput.text = "";
this.resultOutput.setStyle("font-weight","normal");
} else {
this.resultTree.dataProvider = null;
this.resultOutput.text = "No data from a fuzzing run available";
this.resultOutput.setStyle("font-weight","bold");
}
}
/**
* @private
* Save the Response
*/
private function saveResponse():void {
var file:FileReference = new FileReference();
file.save(this.fuzzLog.logXML.toXMLString(), "foo.xml");
}
]]>
</fx:Script>
<!--width="328"-->
<mx:TabNavigator x="19" y="26" width="501" height="562" id="winTN">
<s:NavigatorContent label="LC Sender" width="100%" height="100%" show="setStatus()">
<s:Group>
<s:Label x="10" y="18" text="Target Connection"/>
<s:TextInput x="10" y="36" id="targetConnection" editable="true" width="90%"
toolTip="Enter the name of the Connection used in the connect() call"/>
<s:Label x="10" y="75" text="Target Function"/>
<s:TextInput x="10" y="92" id="targetFunction" editable="true" enabled="true" width="90%"
toolTip="Enter the function that is listening on the above connection"/>
<ParamHandlers:ParamCollection x="10" y="132" id="sendDG" width="90%" includeObject="true"/>
<s:Button x="10" y="386" label="Send Data" click="sendData();"/>
<s:Label x="9" y="457" width="450" height="12" text="Send status:"/>
<s:Label id="sendStatus" x="9" y="473" width="450" height="35"/>
</s:Group>
</s:NavigatorContent>
<s:NavigatorContent label="LC Receiver" width="100%" height="100%">
<s:Group>
<s:Label x="10" y="16" text="Connection Name"/>
<s:TextInput x="10" y="36" id="connectionName" editable="true" enabled="true" width="443"
toolTip="Enter the name of the connection that will be used by the remote SWF"/>
<s:Label x="10" y="73" text="Call Function"/>
<s:TextInput x="10" y="92" id="functionName" editable="true" enabled="true" width="443"
toolTip="Enter the name of the function the remote SWF will be calling."/>
<s:Label x="10" y="131" text="allowDomain setting"/>
<s:TextInput x="10" y="149" width="445" id="allowDomain"
toolTip="Enter the domain or * for the allowDomain setting. For sameDomain, just leave this blank"/>
<s:Button x="10" y="184" label="Add Function" click="receiveFunction()"/>
<s:Label x="12" y="241" text="Data received:"/>
<s:TextArea x="10" y="259" width="443" height="155" id="rOutput" lineBreak="toFit" editable="false" enabled="true"/>
<s:Button x="319" y="422" label="Send to Object Editor" click="sendToOE()"/>
<s:Label x="12" y="463" width="90%" height="12" text="Status updates:"/>
<s:Label id="receiveStatus" x="12" y="477" width="90%" height="23"/>
</s:Group>
</s:NavigatorContent>
<s:NavigatorContent label="LC Fuzzer" width="100%" height="100%" show="setStatus()">
<s:Group>
<s:Label x="11" y="15" width="247" text="Insert XML for fuzz values below:"/>
<s:TextArea x="8" y="34" width="323" height="49" id="fuzzXML"
toolTip="If you want to add custom fuzz values, paste a fuzz.xml file in this box and click add"/>
<s:Button x="358" y="8" label="Add Fuzz Values" click="addFuzzValues()"/>
<s:Button x="358" y="37" label="Clear Defaults" click="clearDefaults()"/>
<s:Button x="358" y="66" label="Reset to Defaults" click="resetToDefaults()"/>
<mx:HRule x="10" y="92" width="465"/>
<s:Label x="10" y="108" text="Target Connection"/>
<s:TextInput x="10" y="128" id="victimConnection" editable="true" width="90%"
toolTip="Enter the name of the connection that the target SWF created"/>
<s:Label x="10" y="166" text="Target Function"/>
<s:TextInput x="10" y="184" id="victimFunction" editable="true" enabled="true" width="90%"
toolTip="Enter the name of the function where the fuzz data will be sent"/>
<ParamHandlers:ParamCollection x="10" y="223" id="fuzzDG" width="90%" showFuzz="true" includeObject="true"/>
<s:Button x="11" y="457" label="Fuzz Endpoint" click="sendMaliciousData();"/>
<s:Label id="fuzzStatus" x="11" y="495" width="464" height="23"/>
</s:Group>
</s:NavigatorContent>
<s:NavigatorContent label="Fuzzer Output" width="100%" height="100%" tabIndex="0" show="initNavigator()">
<s:Group x="0" y="2">
<s:HGroup x="16" y="0" width="483" height="492" verticalAlign="top">
<mx:Tree id="resultTree" height="487" width="207" change="this.treeSelect(event)" iconField="@icon"
folderClosedIcon="@Embed(source='/assets/fuzzer/ResultImage.jpg')"
folderOpenIcon="@Embed(source='/assets/fuzzer/ResultImage.jpg')"
defaultLeafIcon="@Embed(source='/assets/fuzzer/SuccessImage.jpg')"/>
<s:VGroup width="261" height="490" verticalCenter="-51">
<s:TextArea id="resultOutput" width="251" height="484" color="#FFFFFF" contentBackgroundColor="#000000"/>
</s:VGroup>
</s:HGroup>
<s:Button label="Save Response" click="saveResponse()" x="364" y="496"/>
</s:Group>
</s:NavigatorContent>
</mx:TabNavigator>
<fx:Script>
<![CDATA[
private function setStatus():void {
var tempLC:LocalConnection = new LocalConnection();
this.sendStatus.text = tempLC.domain;
}
]]>
</fx:Script>
</s:Application>