Browse Source

Implemeted Bro signature generation for Multistage attacks

Shreyas Srinivasa 8 years ago
parent
commit
18cf8236b1

BIN
res/drawable/ic_bro.png


+ 7 - 1
res/layout/fragment_about.xml

@@ -119,10 +119,16 @@
 			          android:textAlignment="center" android:layout_gravity="right"/>
 			<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
 			          android:textAppearance="?android:attr/textAppearanceMedium"
-			          android:text="Mihai Plasoianu " android:id="@+id/record_conversation_type"
+			          android:text="Mihai Plasoianu "
 			          android:singleLine="false"
 			          android:autoText="false" android:layout_marginTop="4dp"
 			          android:textAlignment="center" android:layout_gravity="right"/>
+			<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
+				android:textAppearance="?android:attr/textAppearanceMedium"
+				android:text="Shreyas Srinivasa " android:id="@+id/record_conversation_type"
+				android:singleLine="false"
+				android:autoText="false" android:layout_marginTop="4dp"
+				android:textAlignment="center" android:layout_gravity="right"/>
 		</LinearLayout>
 	</RelativeLayout>
     </ScrollView>

+ 7 - 0
res/menu/records_detail_actions.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/bro_sig"
+        android:icon="@drawable/ic_bro"
+        android:title="Export as Bro Signature"
+        android:showAsAction="always" />
+</menu>

+ 3 - 0
res/values/strings.xml

@@ -261,6 +261,9 @@
     <string name="profile_warning">Please note, that this profile can\'t be edited. If you make any changes to this profile, a new profile will be created.</string>
     <string name="rec_choose_export_format">Choose export format</string>
     <string name="rec_sync_rec">Synchronize records</string>
+    <string name="bro_signature">Bro Signature </string>
+    <string name="bro_message">This generates a Bro signature policy for this attack</string>
+    <string name="generate">Generate</string>
     <string name="rec_via_bt">Via Bluetooth</string>
     <string name="rec_via_nfc">Via NFC</string>
     <string name="rec_via_online">Via Online Database</string>

+ 63 - 0
src/de/tudarmstadt/informatik/hostage/logging/formatter/BroSignatureGenerator.java

@@ -0,0 +1,63 @@
+package de.tudarmstadt.informatik.hostage.logging.formatter;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+import de.tudarmstadt.informatik.hostage.logging.Record;
+
+/**
+ * Created by root on 01.10.15.
+ */
+public class BroSignatureGenerator extends IntentService{
+
+    public String protocol;
+    public int port;
+    public int port2;
+    public String ip;
+    public String protocol2;
+    public Record crecord;
+
+
+
+    public int protocol2Port(String protocol){
+        if(protocol.contains("HTTP")){port=80;}
+        else if(protocol.contains("MODBUS")){port=502;}
+        else if(protocol.contains("TELNET")){port=23;}
+        else if(protocol.contains("SMB")){port=80;}
+        else if(protocol.contains("HTTPS")){port=443;}
+        else if(protocol.contains("ECHO")){port=7;}
+        else if(protocol.contains("FTP")){port=21;}
+        else if(protocol.contains("MySQL")){port=3306;}
+        else if(protocol.contains("S7COMM")){port=102;}
+        else if(protocol.contains("SIP")){port=1025;}
+        else if(protocol.contains("SMTP")){port=25;}
+        else if(protocol.contains("SNMP")){port=161;}
+        else if(protocol.contains("SSH")){port=22;}
+        return port;
+    }
+
+    public Record getRecordInfo(Record record){
+
+        String recordProtocol=record.getProtocol();
+        String recordRemoteIp = record.getRemoteIP();
+
+
+
+
+
+
+       return crecord;
+    }
+
+
+
+
+    public BroSignatureGenerator(String name) {
+        super(name);
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+
+    }
+}

+ 1 - 1
src/de/tudarmstadt/informatik/hostage/protocol/MODBUS.java

@@ -96,7 +96,7 @@ public class MODBUS implements Protocol {
            // getRequestType(request);
 
             responsePackets=processRequest(request,getRequestType(request));
-            System.out.println(responsePackets);
+
 
 
         }

+ 53 - 3
src/de/tudarmstadt/informatik/hostage/protocol/S7COMM.java

@@ -28,6 +28,8 @@ public class S7COMM implements Protocol {
     //S7COMM Siemens Simatic Parameter codes
 
     public static String DIAGNOSTICS = "0x00";
+    public static String CONNECT = "0x0e";
+    public static String DATA = "0x0f";
     public static String READ = "0x04";
     public static String WRITE = "0x05";
     public static String REQUEST_DOWNLOAD="0x1a";
@@ -63,13 +65,12 @@ public class S7COMM implements Protocol {
 
             //getRequestType(request);
 
-            responsePackets.add(requestPacket); // Response packets have to be studied yet
-            System.out.println(responsePackets);
-
+           // responsePackets.add(requestPacket); // Response packets have to be studied yet
 
 
 
 
+            responsePackets=processRequest(request,getRequestType(request));
 
 
         }
@@ -78,6 +79,24 @@ public class S7COMM implements Protocol {
         return responsePackets;
     }
 
+    private List<Packet> processRequest(byte[] request, int requestType) {
+
+
+        List<Packet> responsePackets = new ArrayList<Packet>();
+
+
+
+
+
+
+
+
+
+        return  responsePackets;
+
+
+    }
+
     @Override
     public TALK_FIRST whoTalksFirst() {
         return null;
@@ -87,4 +106,35 @@ public class S7COMM implements Protocol {
     public String toString(){
         return "S7COMM";
     }
+
+
+    private int getRequestType(byte[] request) {
+
+        int requestType=request[7];
+
+        if (requestType == 5) {
+            requestType = WRITE_COIL;
+        } else if (requestType == 1) {
+            requestType = READ_COILS;
+        } else if (requestType == 6) {
+            requestType = WRITE_SINGLE_REGISTER;
+        } else if (requestType == 4) {
+            requestType = READ_INPUT_REGISTERS;
+        }
+        else if (requestType==2){
+            requestType = READ_INPUT_DISCRETES;
+        }
+        else if (requestType==3){
+            requestType = READ_HOLDING_REGISTERS;
+        }
+
+        System.out.println(requestType);
+        return requestType;
+    }
+
+
+
+
+
+
 }

+ 1 - 12
src/de/tudarmstadt/informatik/hostage/protocol/SNMP.java

@@ -146,9 +146,6 @@ public class SNMP extends BaseAgent implements Protocol {
 
     }
 
-
-
-
     @Override
     protected void addViews(VacmMIB vacmMIB) {
 
@@ -163,10 +160,6 @@ public class SNMP extends BaseAgent implements Protocol {
                 new OctetString(), VacmMIB.vacmViewIncluded, StorageType.nonVolatile);
     }
 
-
-
-
-
         @Override
         protected void registerManagedObjects() {
 
@@ -183,10 +176,6 @@ public class SNMP extends BaseAgent implements Protocol {
         super("");
     }
 
-
-
-
-
         public void start() throws IOException{
 
 
@@ -276,7 +265,7 @@ public class SNMP extends BaseAgent implements Protocol {
 
         agent.registerManagedObject(builder.build());
 
-// Setup the client to use our newly started agent
+        // Setup the client to use our newly started agent
         //client = new SimpleSnmpClient("udp:127.0.0.1/2001");
     }
 

+ 7 - 2
src/de/tudarmstadt/informatik/hostage/services/MultiStage.java

@@ -68,7 +68,9 @@ public class MultiStage extends Service {
 
         Long currentTime = System.currentTimeMillis();
 
-        Long filterTime = (currentTime - 600000);
+        int fetchInterval = 1000 * 60 * 30; // setInterval in millis  Millisec * Second * Minute
+
+        Long filterTime = (currentTime - fetchInterval);
 
         LogFilter filter = new LogFilter();
 
@@ -114,7 +116,10 @@ public class MultiStage extends Service {
             StringBuilder message = new StringBuilder();
             for (Stackbean tmp : b) {
 
-                message.append("\nMulti Stage Attack Detected!\n" + "IP:" + tmp.getRemoteIp() + "\nProtocol:" + tmp.getProtocol());
+               message.append("\nMulti Stage Attack Detected!\n" + "IP:" + tmp.getRemoteIp() + "\nProtocol:" + tmp.getProtocol());
+
+              //  message.append("\nProtocol:" + tmp.getProtocol());
+
 
                 stackRemoteIP=tmp.getRemoteIp();
                 stackLocalIp=tmp.getLocalip();

+ 1 - 1
src/de/tudarmstadt/informatik/hostage/services/MultiStageAlarm.java

@@ -29,7 +29,7 @@ public class MultiStageAlarm extends BroadcastReceiver{
         AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent i = new Intent(context, MultiStageAlarm.class);
         PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
-        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 5, pi); // Millisec * Second * Minute
+        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 3, pi); // Millisec * Second * Minute
 
     }
 

+ 2 - 0
src/de/tudarmstadt/informatik/hostage/services/Stackbean.java

@@ -2,6 +2,8 @@ package de.tudarmstadt.informatik.hostage.services;
 
 /**
  * Created by Shreyas Srinivasa on 21.08.15.
+ *
+ * Bean class to store objects of multistage attack
  */
 public class Stackbean {
 

+ 248 - 2
src/de/tudarmstadt/informatik/hostage/ui/fragment/RecordDetailFragment.java

@@ -1,16 +1,26 @@
 package de.tudarmstadt.informatik.hostage.ui.fragment;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.Context;
 import android.content.DialogInterface;
+import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.os.Environment;
+import android.preference.PreferenceManager;
 import android.text.format.DateFormat;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -19,6 +29,8 @@ import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 import android.widget.TextView;
+import android.widget.Toast;
+
 import de.tudarmstadt.informatik.hostage.R;
 import de.tudarmstadt.informatik.hostage.logging.Record;
 import de.tudarmstadt.informatik.hostage.ui.model.LogFilter;
@@ -43,7 +55,7 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 	/**
 	 * The database helper to retrieve data from the database
 	 */
-	private HostageDBOpenHelper mDBOpenHelper;
+	public HostageDBOpenHelper mDBOpenHelper;
 
 	/**
 	 * The layout inflater
@@ -62,6 +74,10 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 	private TextView mRecordDetailsTextProtocol;
 	private ImageButton mRecordDeleteButton;
 
+	public SharedPreferences pref;
+	public int port;
+	public StringBuilder portArray;
+
 	/**
 	 * Sets the record of which the details should be displayed
 	 * @param rec the record to be used
@@ -93,6 +109,7 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 		setHasOptionsMenu(true);
+		pref = PreferenceManager.getDefaultSharedPreferences(this.getActivity());
 	}
 
 	/**
@@ -213,7 +230,7 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 						.setPositiveButton(R.string.yes,
 								new DialogInterface.OnClickListener() {
 									public void onClick(DialogInterface dialog,
-											int which) {
+														int which) {
 										mDBOpenHelper.deleteByAttackID(mRecord.getAttack_id());
 
 										MainActivity.getInstance().navigateBack();
@@ -225,6 +242,235 @@ public class RecordDetailFragment extends UpNavigatibleFragment {
 		});
 	}
 
+
+	@Override
+	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+		// Inflate the menu items for use in the action bar
+		if (mRecord.getProtocol().contains("HTTP")){
+			inflater.inflate(R.menu.records_detail_actions, menu);
+		}
+		else if (mRecord.getProtocol().contains("MODBUS")){
+			inflater.inflate(R.menu.records_detail_actions, menu);
+		}
+		else if (mRecord.getProtocol().contains("MULTISTAGE")){
+			inflater.inflate(R.menu.records_detail_actions, menu);
+		}
+		else if (mRecord.getProtocol().contains("FILE INJECTION")){
+			inflater.inflate(R.menu.records_detail_actions, menu);
+		}
+	}
+
+	@Override
+	public boolean onOptionsItemSelected(MenuItem item) {
+			switch (item.getItemId()) {
+			case R.id.bro_sig:
+				AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
+				builder.setTitle(MainActivity.getInstance().getString(R.string.bro_signature));
+				builder.setMessage(MainActivity.getInstance().getString(R.string.bro_message));
+
+						builder.setPositiveButton(R.string.generate,
+								new DialogInterface.OnClickListener() {
+									public void onClick(DialogInterface dialog,
+														int which) {
+
+
+										try {
+											getConversation();
+										} catch (IOException e) {
+											e.printStackTrace();
+										}
+
+
+										//mDBOpenHelper.deleteByAttackID(mRecord.getAttack_id());
+
+										MainActivity.getInstance().navigateBack();
+									}
+								}
+						).setNegativeButton(R.string.cancel, null);
+
+
+				builder.create();
+				builder.show();
+
+				return true;
+		}
+		return false;
+	}
+
+
+	public int protocol2Port(String protocol){
+
+		if(protocol.contains("HTTP")){port=80;}
+		else if(protocol.contains("MODBUS")){port=502;}
+		else if(protocol.contains("TELNET")){port=23;}
+		else if(protocol.contains("SMB")){port=80;}
+		else if(protocol.contains("HTTPS")){port=443;}
+		else if(protocol.contains("ECHO")){port=7;}
+		else if(protocol.contains("FTP")){port=21;}
+		else if(protocol.contains("MySQL")){port=3306;}
+		else if(protocol.contains("S7COMM")){port=102;}
+		else if(protocol.contains("SIP")){port=1025;}
+		else if(protocol.contains("SMTP")){port=25;}
+		else if(protocol.contains("SNMP")){port=161;}
+		else if(protocol.contains("SSH")){port=22;}
+		return port;
+	}
+
+	private void getConversation() throws IOException {
+
+
+		ArrayList<Record> conversation = this.mDBOpenHelper.getConversationForAttackID(mRecord.getAttack_id());
+		for (Record r : conversation) {
+
+			String mydata = r.getPacket();
+			ArrayList<String> myTokensList = new ArrayList<String>();
+			String tokens[]=mydata.split("\n");
+			for (String tok : tokens) {
+				if (tok.contains("Protocol:")) {
+					myTokensList.add(tok.split(":")[1]);
+				}
+			}
+
+
+
+			ArrayList<Integer> myPortList = new ArrayList<Integer>();
+
+			//Disaplay the protocols/services
+			for (String tok : myTokensList) {
+				myPortList.add(protocol2Port(tok));
+			}
+			System.out.print(myPortList);
+			String signature = createSignature(r.getRemoteIP(),myPortList);
+			createSignatureFile(signature);
+
+
+		}
+
+	}
+
+	private String createSignature(String ip,ArrayList portList) {
+
+		int portListSize=0;
+		StringBuilder portArray = new StringBuilder();
+
+		for (Object tok : portList) {
+
+			portArray.append(tok+"/tcp");
+			portListSize++;
+			if(portListSize!=portList.size()){
+				portArray.append(",");
+			}
+
+		}
+
+		String defaultSignature = "@load base/frameworks/notice\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"export{\n" +
+				"\tredef enum Notice::Type += {\n" +
+				"\t\tMultistage\n" +
+				"\t};\n" +
+				"}\n" +
+				"global attack_ip ="+ ip+";\n" +
+				"global attack_port = set("+portArray+");\n" +
+				"global attack_count = 0;\n" +
+				"\n" +
+				"\n" +
+				"\n" +
+				"event connection_established(c: connection)\n" +
+				"{\n" +
+				"\n" +
+				"print fmt (\"Initiating.............\");\n" +
+				"print c$id$orig_h;\n" +
+				"print c$id$resp_p;\n" +
+				"\n" +
+				"for (i in attack_port){\n" +
+				"\n" +
+				"\tif(count==0){\n" +
+				"\t\t\n" +
+				"\tif ((c$id$orig_h==attack_ip) && (c$id$resp_p==attack_prot1))\n" +
+				"        {\n" +
+				"\tprint fmt(\"Inside the loop\");\n" +
+				"        ++attack_count;\n" +
+				"\tprint attack_count;\n" +
+				"       }\n" +
+				"\n" +
+				"\telse{break;}\n" +
+				"\t}\n" +
+				"\n" +
+				"  \n" +
+				"\n" +
+				"}\n" +
+				"\n" +
+				" else {\n" +
+				"\n" +
+				"        if ((c$id$orig_h==attack_ip) && (c$id$resp_p == attack_prot2)){\n" +
+				"\t\n" +
+				"\tprint fmt (\"MULTISTAGE ATTACK!!!\");\n" +
+				"        NOTICE([$note = Multistage,\n" +
+				"                $conn = c,\n" +
+				"                $msg = fmt(\"Multistage Attack! from %s\",c$id$orig_h)]);\n" +
+				"\tattack_count = 0;\n" +
+				"\t\n" +
+				"        }\n" +
+				"\n" +
+				" }\n" +
+				"\n" +
+				"\n" +
+				"}\n";
+
+		return defaultSignature;
+	}
+
+	private void createSignatureFile(String signature) throws IOException {
+
+
+		FileOutputStream sig;
+		Long tsLong = System.currentTimeMillis() / 1000;
+		String ts = tsLong.toString();
+		String fileName = "Bro_sig"+ts+".bro";
+		String externalLocation = pref.getString("pref_external_location", "");
+		String root = Environment.getExternalStorageDirectory().toString();
+
+
+		if (root != null && isExternalStorageWritable()) {
+			File dir = new File(root + externalLocation);
+			dir.mkdirs();
+			File file = new File(dir, fileName);
+			sig = new FileOutputStream(file);
+			sig.write(signature.getBytes());
+			sig.write(System.getProperty("line.separator").getBytes());
+			sig.flush();
+			sig.close();
+			Toast.makeText(this.getActivity().getApplicationContext(),"Signature file"+fileName +"created",Toast.LENGTH_LONG).show();
+
+
+		} else {
+			Toast.makeText(this.getActivity(),"Could not write to SD Card",Toast.LENGTH_SHORT).show();
+			return;
+		}
+
+	}
+
+
+
+
+
+
+
+	private boolean isExternalStorageWritable() {
+		String state = Environment.getExternalStorageState();
+		if (Environment.MEDIA_MOUNTED.equals(state)) {
+			return true;
+		}
+		return false;
+	}
+
+
+
+
+
 	/*****************************
 	 * 
 	 * Date Transform