GTE Ė IURP 2000

 

 

Secure Mobile Agents

 

 

 

 

 

 

 

 

Mark Patterson††††††††††††††††††††††††††††††† ††††††††† P.I. ~ Frank Mannix††††††††††††††††††††††††††††††††† August 8, 2000

 

 

 

 

 


Contents

1.†††††††† Abstract............................................................................................................ 3

2.†††††††† Background.................................................................................................... 4

2.1†††††† Terms.................................................................................................................... 4

2.2†††††† Environment.................................................................................................... 4

2.3†††††† Scope..................................................................................................................... 5

2.4†††††† Assumptions...................................................................................................... 5

2.5†††††† Constraints...................................................................................................... 5

3.†††††††† Investigation................................................................................................. 6

3.1†††††† First Approach................................................................................................. 6

3.2†††††† Preliminary Findings................................................................................... 7

3.3†††††† Second Approach........................................................................................... 7

3.4†††††† Secondary Findings...................................................................................... 8

3.5†††††† Ideas...................................................................................................................... 9

4.†††††††† Results............................................................................................................. 10

4.1†††††† Conclusions................................................................................................... 10

4.2†††††† Recommendations....................................................................................... 10

5.†††††††† Evidence........................................................................................................... 11

5.1†††††† Server Source code.................................................................................... 11

5.2†††††† Agent Source Code...................................................................................... 13

 

List of Figures

Figure 1 ~ Agent and its Local Environment............................................................................. 4

Figure 2 ~ Agent and its Global Environment............................................................................ 5

Figure 3 ~ Secure Context Signs the Agent.............................................................................. 6

Figure 4 ~ Secure Context Verifies the Agent.......................................................................... 7

Figure 5 ~ Normal Agent Transfer........................................................................................... 8

Figure 6 ~ Serializing and Transferring a Signed Agent.............................................................. 8

Figure 7 ~ Trusted Signing and Verifying from the Host to the Target........................................ 9

 

1.     Abstract

Telecommunication networks require security testing.Small Java-based agents can carry vulnerability tests to Linux and Windows NT target machines to verify that the target machines are set up securely.These agents require their own security and a trust relationship with the host upon which, they run.Digital signatures utilizing Public Key Encryption (PKE) can provide security for the agents and the agentsí hosts.A Ďhardí problem encryption algorithm may be employed to encrypt the agentís payload (dynamic data area).This project involves exploring the best ways to provide security for the mobile agents and their data while they are traveling to and running on remote systems.

 

 

 

 

2.     Background

 

This investigative report stems from the investigation of secure mobile agents, which the U.S. Army Research Lab (ARL) contracted the Secure Systems Department to perform.The work involves the employment of digital signature and data encryption mechanisms to provide both security and protection of mobile agents and their operation in potentially hostile network environments.This report documents the quest to solve the problem of how to deploy these security mechanisms in the most effective possible manner.

 

2.1     Terms

 

 

Figure 1 ~ Agent and its Local Environment

 

 

n        Agent - autonomous, mobile, proactive, and adaptive software

n        Context - "place" where agent may reside and interact with hosts

n        Server - combined with the context, provides environment where agents may reside and interact with hosts and network.A single server may hold several contexts.

2.2     Environment

 

Generally, mobile agent systems exist in an environment, which consists of a network and two types of hosts: trusted hosts and un-trusted hosts.The trusted host dispatches agents to perform work on an un-trusted host.Subsequently, the agent returns to the trusted host and reports details of the performed work.Figure 2 shows a general model of this environment.

 

 

Figure 2 ~ Agent and its Global Environment

 

2.3     Scope

 

The scope of this investigation involves four components:

 

n        Creation of a digital signature for agents.

n        Verification of an agentís digital signature.

n        Encryption of an agentís collected data.

n        Verification and decryption of collected data.

 

Success is measured when agents have completed their mission of conducting vulnerability tests on un-trusted targets and have returned to the trusted host uncorrupted with gathered, encrypted test data.

 

2.4     Assumptions

 

The assumption is that at some point in the future, a Public Key Infrastructure (PKI) will be available to provide certificate authorities, security services, and encryption technology to protect agent communications and agent transactions over a network.

 

2.5     Constraints

 

The agent development platform selected by ARL is the IBM Aglet Work Bench (AWB) version 1.0.3.AWB version 1.0.3 is based on Java version 1.1.Due to ARL's selection, the project must employ AWB version 1.0.3 and Java version 1.1 including each of their inherent security architectures.

 

3.     Investigation

 

I created and employed a test bed consisting of a trusted host and an un-trusted target computer to develop and test the system.Both the host and the target run individual agent servers - each capable of creating multiple contexts within which agents may independently execute.

 

The agent context, an interface layer within the agent runtime environment of the agent server, is clearly the choice for implementation of agent security services within a host computer.It is within the context that agentsí threads of execution can be precisely controlled and effective control of agents at the process level removes concerns about rogue or malicious agents.

Additionally, I discovered that I could take control of the agent's serialization process; this allows creation of a digital signature of the agent and its state independent from the environment within which the agent executes.

 

3.1     First Approach

 

The first approach was to find a way to extend, overwrite, or override the context interface layer and consequently implement the new security system utilizing both PKE and a data encryption algorithm to secure and protect both the mobile agent and its gathered data.

 

This approach develops a secure context within the server.The main context dispatches the agent to the secure context.This secure context has read access to a private key located somewhere on the trusted host.This secure context creates a digital signature of the agentís serialized data stream utilizing the hostís private key.The agentís serial data stream is then re-packaged into the form: | Header | Serialized Agent | Digital Signature | where the Header is a four-byte integer which represents the length of the Serialized Agent.Figure 3 illustrates the relationship between the context, the secure context, the server, the trusted host, and the private key.

Figure 3 ~ Secure Context Signs the Agent

 

After re-packaging the serial data stream, the secure context dispatches this re-packaged, serialized, data stream to the un-trusted target host.The un-trusted host only accepts agents into a secure context.This secure context breaks up the agentís serial data stream into the primitive forms: | Header | Serialized Agent | Digital Signature | and consequently, verifies the agentís digital signature using the trusted hostís public key.Figure 4 illustrates the relationship between the context, the secure context, the server, the un-trusted host, and the public key.

Figure 4 ~ Secure Context Verifies the Agent

3.2     Preliminary Findings

 

I found AWB to be a ďblack boxĒ Ė poorly documented and not open sourced.AWB frustrated various attempts to extend, overwrite, or override either the runtime daemon or the context interface.

 

Attempts to extend, overwrite, or override the methods written into AWB's implementation of the agent context were unsuccessful.Attempts to overwrite, override, substitute, or replace AWB's replacement of the Java Virtual Machine's Security Manager in AWBís runtime environment were also unsuccessful.

 

Extensive research supported the conclusion that unless the AWB became open source, neither of these two tasks can be accomplished within the constraints of AWB version 1.0.3 and Java version 1.1.

 

Consequently, efforts focused on the agent itself.Investigation of the process of agent serialization within the AWB revealed that it was possible to replace the agentís default serialization routines.Control of the agentís serialization process enables the ability to create a digital signature on the agentís serialized object, state, and data.

 

3.3     Second Approach

 

I successfully developed overriding serialization and de-serialization routines.During the first step of normal agent transfer, the runtime environment suspends the agent's threads of execution.Next, the environment serializes the agent and encodes the agents Object Code and Execution State.Finally, the environment sends the fully serialized, encoded agent out over the network via Agent Transfer Protocol (ATP).These new routines override the AWB's default serialization and de-serialization processes.Figure 5 describes the normal agent transfer between two hosts: a sender and a receiver.

Figure 5 ~ Normal Agent Transfer

 

I incorporated these serialization and de-serialization routines into the agentís code.The new serialization routines digitally sign the agentís object code using PKE and encrypt the agentís gathered data using a simple substitution encryption algorithm.The de-serialization routines verify the agentís digital signature and decrypt the agentís gathered data.Figure 6 describes the serialization, transfer, and de-serialization processes of a signed agent.

 

Figure 6 ~ Serializing and Transferring a Signed Agent

 

Overriding the agent's serialization process involves marshalling the agent's Object Code, its resources, and its Execution State and serializing this data.Next, a private key creates a digital signature on this serialized data.Finally, the serial data stream travels over the network via ATP as a formatted structure with the form: | Header | Serialized Agent | Digital Signature | where the Header is a four-byte integer which represents the length of the Serialized Agent.

 

Upon receipt of the ATP transmission from across the network, the receiving host reads the formatted, serialized, data stream.The receiving host then breaks up the agent's data stream into the primitive forms: | Header | Serialized Agent | Digital Signature |.Subsequently, the receiving host verifies the agentís digital signature using the sending hostís public key.Lastly, the agent is re-instantiated and resumes its pre-dispatch execution state.

 

3.4     Secondary Findings

 

This process enables successful signing and verification of an agent using PKE and provides the agent with self-awareness of its own authenticity or lack thereof.This method, however, does not provide the establishment of a trust relationship between the incoming agent and the host.

 

While one may overwrite instance variables in an agent, a mobile agent should never have access to any private keys on any host.

 

Although the agentís verification routine runs before instantiation of the agent on the remote host, the fact that an incoming agent is able to run any routine on the remote host prior to verification of the agent illuminates a large hole in the security of the AWB implementation of an agent framework.

 

3.5     Ideas

 

Secure mobile agents are an achievable goal;a hybrid system can sign and verify a mobile agent.In this system, a stationary agent on the trusted host has access to the hostís private key.The mobile agent passes its serialized data stream to this stationary agent for signing via the agent messaging mechanism.The stationary agent then signs the data stream and passes the signature back to the mobile agent again via the agent messaging mechanism.The mobile agent consequently packages itself as described earlier: | Header | Serialized Agent | Digital Signature | and sends the serial data stream to travel over the network via ATP.

 

The receiving host has an independent application listening for incoming agents, written in C and independent of the constraints and security limitations of Java 1.1.This program screens all incoming agents, breaks up the incoming agentsí data stream into the primitive forms (if the forms exist): | Header | Serialized Agent | Digital Signature |, and verifies the agentsí digital signature.Finally, the C program sends the verified Serialized Agents via ATP to a specific context on the receiving host, which only accepts ATP transmissions of local IP origin.Figure 7 graphically depicts this scenario.

 

Figure 7 ~ Trusted Signing and Verifying from the Host to the Target

4.     Results

 

I investigated various approaches to securing mobile agents and produced a mobile agent that is secure in relation to itself.More research effort is needed to achieve the establishment of a trust relationship between a free and mobile agent and an un-trusting host in a potentially hostile network environment.

 

4.1     Conclusions

Java version 1.1 is an antiquated technology and investigation indicates the more robust Java 2 platform with its inherent security features is better suited for providing security services for a mobile agent.AWB version 1.0.3 is a proprietary agent framework and no longer appears to be maintained by its owner, IBM.An open sourced agent framework is better suited for the development and the deployment of security services for mobile agents.

 

The most effective and most appropriate implementation of multiple level security for mobile agents is within the serverís context.Controlling agentsí threads of execution within the context effectively removes any concerns about rogue or malicious agents.Additionally, a trust relationship with the agent can be established within the context.

 

The addition of Secure Socket Layers (SSL) to the agent framework significantly enhances the robustness of agent security in a potentially hostile global environment.

 

4.2     Recommendations

 

The following steps will help enable security for mobile agents as they travel and run on remote systems:

 

1)                  Upgrade from Java Platform version 1.1 to Java 2.

2)                  Employ an open sourced agent framework.

3)                  Investigate the feasibility of incorporating SSL into the agent framework.

 

 

5.     Evidence

5.1     Server Source code

 

/*

* Server.java

*

* =======================================================================

*

*Version:1†† Aug 2000

*

*Copyright 2000 Verizon

*

* This module is free software; you can redistribute it and/or

* modify it under the terms of the GNU General Public License as

* published by the Free Software Foundation; either version 2 of the

* License, or (at your option) any later version.

*

* THIS SOFTWARE IS DISTRIBUTED "AS IS" WITHOUT WARRANTY OF ANY KIND,

* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED

* WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE

*

* See the GNU General Public License for more details.

*

* You should have received a copy of the GNU General Public License

* along with this program; if not, write to the Free Software

* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*

*Author:

*

*††††††† Mark Patterson

*

*Modifications:

*††

*††††††† 8/2/00 - Frank Mannix - Inserted header and comments

*

*

* =======================================================================

*

*

* Purpose:Part of a demo to show how to incorporate digital signature

*†††††††††† and encryption.

*

* =======================================================================

*/

/* Aglets server */

 

import java.io.*;

import com.ibm.aglet.*;

import com.ibm.atp.daemon.*;

import com.ibm.aglet.system.*;

import java.io.IOException;

 

 

public class Server {

private AgletContext context;

private AgletContext contexta;

†††

Server( String [] args ) {

††† try{

††††† if ( Main.importOptions(args) == false )

††††† throw new IOException();

††† }

††† catch( IOException ioe ){

††††† System.err.println( "Unvalid options for the server. Aborting!" );

††††† System.exit( 1 );

††† }

†††

††† Daemon daemon = Daemon.init( args );

†††

††† AgletRuntime runtime = AgletRuntime.init( args );

†††

†† context = runtime.createAgletContext( "a" );

†††

††† daemon.start( "aglets" );

†††

††† context.start();

†††

†††

††† // Begin to listen to new aglets

††† context.addContextListener( new listen() );

††† }

class listen extends ContextAdapter {

††

††† public void agletCreated( ContextEvent ev ){

††††† AgletProxy proxy = ev.getAgletProxy();

††††† try{

††††† System.out.println( "Aglet is being created:\n"

††††††††††††††††† ††† +proxy.getAgletInfo() );

††††† }

††††† catch( InvalidAgletException ie ){

††††† System.err.println( ie );

††††† }

††† }

†††

 

††† public void agletArrived( ContextEvent ev ){

††††† AgletProxy proxy = ev.getAgletProxy();

††††† try{

††††† System.out.println( "Aglet is arriving:\n"

††††††††††††††††† ††† +proxy.getAgletInfo() );

††††† }

††††† catch( InvalidAgletException ie ){

††††† System.err.println( ie );

††††† }

††† }

†††

††† public void agletDispatched( ContextEvent ev ){

††††† AgletProxy proxy = ev.getAgletProxy();

††††† try{

††††† System.out.println( "Aglet is leaving:\n"

††††††††††††††††† ††† +proxy.getAgletInfo() );

††††† }

††††† catch( InvalidAgletException ie ){

††††† System.err.println( ie );

††††† }

††† }

†††

††† public void agletDisposed( ContextEvent ev ){

††††† AgletProxy proxy = ev.getAgletProxy();

††††† try{

††††† System.out.println( "Aglet is being disposed of:\n"

††††††††††††††††† ††† +proxy.getAgletInfo() );

††††† }

††††† catch( InvalidAgletException ie ){

††††† System.err.println( ie );

††††† }

††† }

}†††

 

public static void main(String argv[]){

††† /* Starts the server */

††† String args[]={"-nosecurity", "-port", "9002"};

††† Server Serve = new Server( args );

††† System.out.println( "\nHost: " + Serve.context.getHostingURL() + "\n");

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.2     Agent Source Code

 

/*

* GoBack.java

*

* =======================================================================

*

*Version:1†† Aug 2000

*

*Copyright 2000 Verizon

*

* This module is free software; you can redistribute it and/or

* modify it under the terms of the GNU General Public License as

* published by the Free Software Foundation; either version 2 of the

* License, or (at your option) any later version.

*

* THIS SOFTWARE IS DISTRIBUTED "AS IS" WITHOUT WARRANTY OF ANY KIND,

* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED

* WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE

*

* See the GNU General Public License for more details.

*

* You should have received a copy of the GNU General Public License

* along with this program; if not, write to the Free Software

* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*

*Author:

*

*††††††† Mark Patterson

*

*Modifications:

*††

*††††††† 8/2/00 - Frank Mannix - Inserted header and comments

*

*

* =======================================================================

*

*

* Purpose:Part of a demo to show how to incorporate digital signature

*†††††††††† and encryption.

*

* =======================================================================

*/

 

 

/* Test aglet */

 

import java.io.*;

import java.net.URL;

import com.ibm.aglet.*;

import java.security.*;

 

public class GoBack extends Aglet implements ObjectInputValidation {

 

††††† private int outfilesize;

††††† private int infilesize;

††††† private boolean signing = false;

††††† private byte[] sig;

††††† private PrivateKey priv;

††††† private Signature dsa ;

††††† private byte[] signat;

††††† URL home = null, remote = null;

††††† boolean local = true, firstTime = true;

††††† StringBuffer buffer, blackbuffer, clearbuffer;

 

public void getLocalInfo() {

††††† AgletContext ac = getAgletContext();

††††† buffer.append((String)ac.getProperty("aglets.user.name", "Unknown"));

††††† buffer.append("\n");

††††† buffer.append((String)ac.getProperty("aglets.user.organization", "Unknown"));

††††† buffer.append("\n");

††††† buffer.append((String)ac.getProperty("aglets.user.email", "Unknown"));

††††† buffer.append("\n");

††† }

 

private void readObject(ObjectInputStream in)

††††† throws IOException, ClassNotFoundException {

††††† in.registerValidation(this, 0);

††††† infilesize = in.readInt();

††††† in.defaultReadObject();

††††† blackbuffer = (StringBuffer)in.readObject();

††††† signat = (byte[])in.readObject();

††††† }

 

public void validateObject()throws InvalidObjectException {

 

††††† byte b[];

††††† signing = true;

††††† ByteArrayOutputStream bs = new ByteArrayOutputStream();

 

††††† for(int i = 0; i < blackbuffer.length(); i++) {

††††††††††† clearbuffer.append((char)((int)blackbuffer.charAt(i) - 1));

††††† }

 

††††† try {

††††††††††† ObjectOutputStream os = new ObjectOutputStream(bs);

††††††††††† os.writeObject(this);

††††††††††† os.flush();

††††††††††† b = bs.toByteArray();

††††††††††† os.close();

††††† } catch (IOException e) {

††††††††††† throw new InvalidObjectException("IOException");

††††† }

††††† signing = false;

 

††††† try {

 

††††††††††† /* load stored public key */

††††††††††† ObjectInputStream pubOIS = new ObjectInputStream(new FileInputStream("tmp/pub.key"));

††††††††††† Object pubCopy = pubOIS.readObject();

††††††††††† pubOIS.close();

††††††††††† PublicKey pub = (PublicKey)pubCopy;

 

††††††††††† /* create a Signature object to use for verifying */

††††††††† ††Signature dsain = Signature.getInstance("SHA/DSA");

 

††††††††††† /* verify signature of signed object using public key and report */

††††††††††† dsain.initVerify(pub);

 

††††††††††† /* Update and sign the data */

††††††††††† dsain.update(b);

 

††††††††††† /* Verify the signature */

††††††††††† boolean verifies = dsain.verify(signat);

††††††††††† System.out.println("\nsignature verifies: " + verifies + "\n");††

††††††††††† }

††††††††††† catch (Exception e) {

††††††††††† ††††† System.err.println("\nCaught exception " + e.toString());††

††††††††††† }

††††† }

 

private void writeObject(ObjectOutputStream out)throws IOException {

 

††††† byte ba[];

††††† if (!signing) {

††††††††††† signing = true;

††††††††††† ByteArrayOutputStream bs = new ByteArrayOutputStream();

††††††††††† ObjectOutputStream os = new ObjectOutputStream(bs);

††††††††††† os.writeObject(this);

††††††††††† os.flush();

††††††††††† ba = bs.toByteArray();

††††††††††† os.close();

 

††††††††††† try {

††††††††††††††††† //load stored private key

††††††††††††††††† ObjectInputStream priOIS = new ObjectInputStream(new FileInputStream("tmp/priv.key"));

††††††††††††††††† Object priCopy = priOIS.readObject();

††††††††††††††††† priOIS.close();

††††††††††††††††† priv = (PrivateKey)priCopy;

 

††††† ††††† ††††††// create a Signature object to use for signing

 

††††† ††††† ††††††Signature dsa = Signature.getInstance("SHA/DSA");

 

††††† ††††† ††††††// initialize the Signature object for signing

 

††††† ††††† ††††††dsa.initSign(priv);

 

††††† ††††† ††††††// Update and sign the data

 

††††††††††††††††† dsa.update(ba);

 

†††† ††††† ††††††sig = dsa.sign();

 

††††††††††††††††† outfilesize = ba.length;

††††††††††††††††† signing = false;

 

††††††††††††††††† out.writeInt(outfilesize);

††††††††††††††††† out.defaultWriteObject();

††††††††††††††††† out.writeObject(blackbuffer);

††††††††††††††††† out.writeObject(sig);

††††††††††††††††† }

††††††††††††††††† catch (Exception e) {

††††† ††††††††††† ††††† System.err.println("Caught exception " + e.toString());††††

††††††††††††††††† }††

††††††††††† }

††††† }

†††

††† public void onCreation( Object init ) {

††††† try {

††††† ††† remote = new URL( (String)init );

††††† }

††††† catch( Exception e ) {

††††† ††† System.err.println( "Init object is not a valid URL! " );

††††† ††† dispose();

††††† }

†††††

††††† /* Initialize the variables. */

††††† home = getAgletContext().getHostingURL();

††††† buffer = new StringBuffer();

††††† blackbuffer = new StringBuffer();

††††† clearbuffer = new StringBuffer();

 

††††† System.out.println( "I am alive. I will go from " + home

††††††††††††††††† ††† + " to " + remote );

††††† }

 

†† public void run() {

††††† try {

††††††††††† if ( local ) {

††††††††††††††††† if ( firstTime ) {

††††††††††††††††††††††† local = false;

††††††††††††††††††††††† firstTime = false;

††††††††††††††††††††††† System.out.println( "Dispatching myself..." );

††††††††††††††††††††††† dispatch( remote );

††††††††††††††††† }

††††††††††††††††† else {

††††††††††††††††††††††† System.out.println( "I am back." );

††††††††††††††††††††††† System.out.println( "buffer:\n" + buffer );

††††††††††††††††††††††† System.out.println( "blackbuffer:\n" + blackbuffer );

††††††††††††††††††††††† System.out.println( "\nclearbuffer:\n" + clearbuffer );

††††††††††††††††††††††† dispose();

††††††††††††††††† }

††††††††††† }

††††††††††† else {

††††††††††††††††† local = true;

††††††††††††††††† System.out.println( "Arriving on the remote platform.\n"

††††††††††††††††††††††† ††† +"Going back now..." );

††††††††††††††††† getLocalInfo();

††††††††††††††††† for(int i = 0; i < buffer.length(); i++) {

††††††††††††††††††††††† blackbuffer.append((char)((int)buffer.charAt(i) + 1));

††††††††††††††††† }

††††††††††††††††† buffer.setLength(0);

††††††††††††††††† dispatch( home );

††††††††††† }

††††† }

††††† catch( Exception e ) {

††††††††††† System.err.println( "Could not dispatch, because: ");

††††††††††† e.printStackTrace();

††††† }

†† }

}