Browse Source

-Added documentation about RFC and handable requests
-some code refactoring for protocols

Wulf Pfeiffer 10 years ago
parent
commit
eabd3af51f

+ 1 - 1
src/de/tudarmstadt/informatik/hostage/HoneyService.java

@@ -451,7 +451,7 @@ public class HoneyService extends Service {
 		@Override
 		protected void onPostExecute(String result) {
 			if (result != null)
-				HTTP.setHtmlDocContent(result);
+				HTTP.setHtmlDocumentContent(result);
 		}
 	};
 	

+ 9 - 8
src/de/tudarmstadt/informatik/hostage/protocol/ECHO.java

@@ -6,10 +6,11 @@ import java.util.List;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * ECHO protocol
+ * ECHO protocol. Implementation of RFC document 862.
+ * 
  * @author Wulf Pfeiffer
  */
-public class ECHO implements Protocol{
+public class ECHO implements Protocol {
 
 	@Override
 	public int getDefaultPort() {
@@ -20,12 +21,12 @@ public class ECHO implements Protocol{
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.CLIENT;
 	}
-	
+
 	@Override
-	public List<Packet> processMessage(Packet packet) {
-		List<Packet> response = new ArrayList<Packet>();
-		response.add(packet);
-		return response;
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		responsePackets.add(requestPacket);
+		return responsePackets;
 	}
 
 	@Override
@@ -42,7 +43,7 @@ public class ECHO implements Protocol{
 	public Class<byte[]> getType() {
 		return byte[].class;
 	}
-	
+
 	@Override
 	public String toString() {
 		return "ECHO";

+ 28 - 26
src/de/tudarmstadt/informatik/hostage/protocol/FTP.java

@@ -6,7 +6,9 @@ import java.util.List;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * FTP protocol
+ * FTP protocol.
+ * Implementation of RFC document 959.
+ * It can handle the following requests: USER, PASS, QUIT.
  * @author Wulf Pfeiffer
  */
 public class FTP implements Protocol {
@@ -34,20 +36,20 @@ public class FTP implements Protocol {
 	}
 
 	@Override
-	public List<Packet> processMessage(Packet packet) {
+	public List<Packet> processMessage(Packet requestPacket) {
 		String request = null;
-		if (packet != null) {
-			request = packet.toString();
+		if (requestPacket != null) {
+			request = requestPacket.toString();
 		}
-		List<Packet> response = new ArrayList<Packet>();
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		switch (state) {
 		case NONE:
 			if (request == null) {
 				state = STATE.OPEN;
-				response.add(new Packet(c220));
+				responsePackets.add(new Packet(REPLY_CODE_220));
 			} else {
 				state = STATE.CLOSED;
-				response.add(new Packet(c421));
+				responsePackets.add(new Packet(REPLY_CODE_421));
 			}
 			break;
 		case OPEN:
@@ -55,51 +57,51 @@ public class FTP implements Protocol {
 				state = STATE.CLOSED;
 				return null;
 			} else if (request.equals("USER \r\n")) {
-				response.add(new Packet(c501));
+				responsePackets.add(new Packet(REPLY_CODE_501));
 			} else if (request.contains("USER")) {
 				state = STATE.USER;
-				response.add(new Packet(c331));
+				responsePackets.add(new Packet(REPLY_CODE_331));
 			} else {
-				response.add(new Packet(c332));
+				responsePackets.add(new Packet(REPLY_CODE_332));
 			}
 			break;
 		case USER:
 			if (request.equals("PASS \r\n")) {
 				state = STATE.OPEN;
-				response.add(new Packet(c501));
+				responsePackets.add(new Packet(REPLY_CODE_501));
 			} else if (request.contains("PASS")) {
 				state = STATE.LOGGED_IN;
-				response.add(new Packet(c230));
+				responsePackets.add(new Packet(REPLY_CODE_230));
 			} else {
 				state = STATE.CLOSED;
-				response.add(new Packet(c221));
+				responsePackets.add(new Packet(REPLY_CODE_221));
 			}
 			break;
 		case LOGGED_IN:
 			if (request != null && !request.contains("QUIT")) {
-				response.add(new Packet(c500));
+				responsePackets.add(new Packet(REPLY_CODE_500));
 			} else {
 				state = STATE.CLOSED;
-				response.add(new Packet(c221));
+				responsePackets.add(new Packet(REPLY_CODE_221));
 			}
 			break;
 		default:
 			state = STATE.CLOSED;
-			response.add(new Packet(c421));
+			responsePackets.add(new Packet(REPLY_CODE_421));
 		}
-		return response;
+		return responsePackets;
 	}
 	
 	//commands
-	private String c220 = "220 Service ready for new user.";
-	private String c221 = "221 Service closing control connection.";
-	private String c230 = "230 User logged in.";
-	private String c331 = "331 User name ok, need password.";
-	private String c332 = "332 Need account for login.";
-	private String c421 = "421 Service not available, closing control connection.";
-	private String c500 = "500 Syntax error, command unrecognized.";
-	private String c501 = "501 Syntax error in parameters or arguments";
-	
+	private static final String REPLY_CODE_220 = "220 Service ready for new user.";
+	private static final String REPLY_CODE_221 = "221 Service closing control connection.";
+	private static final String REPLY_CODE_230 = "230 User logged in.";
+	private static final String REPLY_CODE_331 = "331 User name ok, need password.";
+	private static final String REPLY_CODE_332 = "332 Need account for login.";
+	private static final String REPLY_CODE_421 = "421 Service not available, closing control connection.";
+	private static final String REPLY_CODE_500 = "500 Syntax error, command unrecognized.";
+	private static final String REPLY_CODE_501 = "501 Syntax error in parameters or arguments";
+
 	@Override
 	public boolean isClosed() {
 		return state == STATE.CLOSED;

+ 38 - 27
src/de/tudarmstadt/informatik/hostage/protocol/GhostProtocol.java

@@ -9,13 +9,21 @@ import java.util.List;
 
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
+/**
+ * Ghost Protocol. This protocol mirrors an incoming connection back to the
+ * attacker on the same port, that it is running on. It will send all incoming
+ * requests back to the attacker on the mirrored connection and will relpy with
+ * the responses it get's from this mirrored connection.
+ * 
+ * @author Wulf Pfeiffer
+ */
 public class GhostProtocol implements Protocol {
-	
+
 	private boolean isClosed = false;
 
 	@Override
 	public int getDefaultPort() {
-		return 5050;
+		return 5050; // TODO dynamic port / whats the default!? (1433)
 	}
 
 	@Override
@@ -24,39 +32,42 @@ public class GhostProtocol implements Protocol {
 	}
 
 	@Override
-	public List<Packet> processMessage(Packet packet) {		
-		List<Packet> response = new ArrayList<Packet>();
-		try {			
-			if(attacker == null) {
-				attacker = new Socket("127.0.0.1", 5050);
-				in = new BufferedInputStream(attacker.getInputStream());
-				out = new BufferedOutputStream(attacker.getOutputStream());
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		try {
+			if (mirroredConnection == null) {
+				mirroredConnection = new Socket("192.168.178.86", 5050); // TODO
+				mirrorInputStream = new BufferedInputStream(
+						mirroredConnection.getInputStream());
+				mirrorOutputStream = new BufferedOutputStream(
+						mirroredConnection.getOutputStream());
 			}
-			if(attacker.isInputShutdown() || attacker.isOutputShutdown()) {
-				in.close();
-				out.close();
-				attacker.close();
+			if (mirroredConnection.isInputShutdown()
+					|| mirroredConnection.isOutputShutdown()) {
+				mirrorInputStream.close();
+				mirrorOutputStream.close();
+				mirroredConnection.close();
 				isClosed = true;
 			}
-			
-			out.write(packet.getMessage());
-			out.flush();
-			
+
+			mirrorOutputStream.write(requestPacket.getMessage());
+			mirrorOutputStream.flush();
+
 			int availableBytes;
-			while((availableBytes = in.available()) <= 0) {
+			while ((availableBytes = mirrorInputStream.available()) <= 0) {
 				try {
 					Thread.sleep(1);
 				} catch (InterruptedException e) {
 					e.printStackTrace();
 				}
 			}
-			byte[] answer =  new byte[availableBytes];
-			in.read(answer);
-			response.add(new Packet(answer));
+			byte[] mirrorResponse = new byte[availableBytes];
+			mirrorInputStream.read(mirrorResponse);
+			responsePackets.add(new Packet(mirrorResponse));
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
-		return response;
+		return responsePackets;
 	}
 
 	@Override
@@ -73,13 +84,13 @@ public class GhostProtocol implements Protocol {
 	public Class<byte[]> getType() {
 		return byte[].class;
 	}
-	
+
 	@Override
 	public String toString() {
 		return "GhostProtocol";
 	}
-	
-	Socket attacker;
-	BufferedInputStream in;
-	BufferedOutputStream out;
+
+	private Socket mirroredConnection;
+	private BufferedInputStream mirrorInputStream;
+	private BufferedOutputStream mirrorOutputStream;
 }

+ 62 - 52
src/de/tudarmstadt/informatik/hostage/protocol/HTTP.java

@@ -13,7 +13,10 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 
 /**
- * HTTP protocol
+ * HTTP protocol.
+ * Implementation of RFC document 1945.
+ * It can handle the following requests: GET, HEAD, TRACE, POST, DELETE.
+ * For all other requests '400 Bad Request' will be replied.
  * @author Wulf Pfeiffer
  */
 public class HTTP implements Protocol {
@@ -29,36 +32,36 @@ public class HTTP implements Protocol {
 	}
 	
 	@Override
-	public List<Packet> processMessage(Packet packet) {
+	public List<Packet> processMessage(Packet requestPacket) {
 		String request = null;
-		if (packet != null) {
-			request = packet.toString();
+		if (requestPacket != null) {
+			request = requestPacket.toString();
 		}
-		List<Packet> response = new ArrayList<Packet>();
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		this.request = request;
 
 		if(!request.contains(httpVersion)){
-			response.add(buildPacket(c505, ""));
-		} else if(request.contains(get)) {
-			response.add(buildPacket(c200, get));
-		} else if(request.contains(head)) {
-			response.add(buildPacket(c200, head));
-		} else if(request.contains(trace)){
-			response.add(buildPacket(c200, trace));
-		} else if(request.contains(options)){
-			response.add(buildPacket(c400, options));
-		} else if(request.contains(post)){
-			response.add(buildPacket(c200, post));
-		} else if(request.contains(put)){
-			response.add(buildPacket(c400, put));
-		} else if(request.contains(delete)){
-			response.add(buildPacket(c200, delete));
-		} else if(request.contains(connect)){
-			response.add(buildPacket(c400, connect));
+			responsePackets.add(buildPacket(STATUS_CODE_505, ""));
+		} else if(request.contains(GET)) {
+			responsePackets.add(buildPacket(STATUS_CODE_200, GET));
+		} else if(request.contains(HEAD)) {
+			responsePackets.add(buildPacket(STATUS_CODE_200, HEAD));
+		} else if(request.contains(TRACE)){
+			responsePackets.add(buildPacket(STATUS_CODE_200, TRACE));
+		} else if(request.contains(OPTIONS)){
+			responsePackets.add(buildPacket(STATUS_CODE_400, OPTIONS));
+		} else if(request.contains(POST)){
+			responsePackets.add(buildPacket(STATUS_CODE_200, POST));
+		} else if(request.contains(PUT)){
+			responsePackets.add(buildPacket(STATUS_CODE_400, PUT));
+		} else if(request.contains(DELETE)){
+			responsePackets.add(buildPacket(STATUS_CODE_200, DELETE));
+		} else if(request.contains(CONNECT)){
+			responsePackets.add(buildPacket(STATUS_CODE_400, CONNECT));
 		} else {
-			response.add(buildPacket(c400, ""));
+			responsePackets.add(buildPacket(STATUS_CODE_400, ""));
 		}
-		return response;
+		return responsePackets;
 	}
 
 	@Override
@@ -88,13 +91,18 @@ public class HTTP implements Protocol {
 	 * @return the html response
 	 */
 	private Packet buildPacket(String code, String type) {
-		String doc = "";
-		if(type.equals(get)) doc = htmlDoc;
-		else if(type.equals(head) || type.equals(delete)) doc = "";
-		else if(type.equals(trace)) doc = request;
-		else doc = errorHtmlPrefix + " " + code + errorHtmlSuffix;
+		String document = "";
+		if (type.equals(GET)) {
+			document = htmlDocument;
+		} else if (type.equals(HEAD) || type.equals(DELETE)) {
+			document = "";
+		} else if (type.equals(TRACE)) {
+			document = request;
+		} else {
+			document = errorHtmlPrefix + " " + code + errorHtmlSuffix;
+		}
 
-		return new Packet(httpVersion + " " + code + headerPrefix + doc.length() + headerSuffix + doc);
+		return new Packet(httpVersion + " " + code + headerPrefix + document.length() + headerSuffix + document);
 	}
 	
 	/**
@@ -125,22 +133,23 @@ public class HTTP implements Protocol {
 	}
 	private String httpVersion	= "HTTP/1.1";
 	private static String serverVersion = initServerVersion();
-	private static String htmlDocContent = HelperUtils.getRandomString(32, false);
+	private static String htmlDocumentContent = HelperUtils.getRandomString(32, false);
 	//request codes
-	private String options 	= "OPTIONS";
-	private String get 		= "GET";
-	private String head 	= "HEAD";
-	private String post		= "POST";
-	private String put		= "PUT";
-	private String delete	= "DELETE";
-	private String trace	= "TRACE";
-	private String connect	= "CONNECT";
-	private String c200 	= "200 OK\r\n";
-	private String c400 	= "400 Bad Request\r\n";
-	private String c505 	= "505 HTTP Version not supported\r\n";
+	private static final String OPTIONS	= "OPTIONS";
+	private static final String GET 	= "GET";
+	private static final String HEAD 	= "HEAD";
+	private static final String POST	= "POST";
+	private static final String PUT		= "PUT";
+	private static final String DELETE	= "DELETE";
+	private static final String TRACE	= "TRACE";
+	private static final String CONNECT	= "CONNECT";
+	
+	private static final String STATUS_CODE_200	= "200 OK\r\n";
+	private static final String STATUS_CODE_400	= "400 Bad Request\r\n";
+	private static final String STATUS_CODE_505	= "505 HTTP Version not supported\r\n";
 	
 	//html header pre and suffix
-	private static final String headerPrefix =				
+	private String headerPrefix =				
 			"Date: " + getServerTime() + "\r\n" +
 			"Server: " + serverVersion + " \r\n" +
 			"Vary: Accept-Encoding\r\n" +
@@ -152,13 +161,13 @@ public class HTTP implements Protocol {
 			"Content-Type: text/html\r\n" +
 			"\r\n";
 	//html website
-	private String htmlDoc = 
+	private String htmlDocument = 
 			"<!doctype html>\n" +
 			"<html lang=\"en\">\n" +
 			"<head>\n" +
 			"<meta charset=\"UTF-8\">\n" +
-			"<title>" + htmlDocContent + "</title>\n" +
-			"<body>" + htmlDocContent + "</body>\n" +
+			"<title>" + htmlDocumentContent + "</title>\n" +
+			"<body>" + htmlDocumentContent + "</body>\n" +
 			"</head>\n" +
 			"</html>";
 	//html error pre and suffix
@@ -172,12 +181,13 @@ public class HTTP implements Protocol {
 			"</title>\n" +
 			"</head>\n" +
 			"</html>";
-	
-	public static String getHtmlDocContent() {
-		return htmlDocContent;
-	}
 
-	public static void setHtmlDocContent(String htmlDocContent) {
-		HTTP.htmlDocContent = htmlDocContent;
+	/**
+	 * Sets the html document content for HTTP and HTTPS.
+	 * 
+	 * @param htmlDocumentContent
+	 */
+	public static void setHtmlDocumentContent(String htmlDocumentContent) {
+		HTTP.htmlDocumentContent = htmlDocumentContent;
 	}
 }

+ 20 - 17
src/de/tudarmstadt/informatik/hostage/protocol/HTTPS.java

@@ -8,7 +8,8 @@ import javax.net.ssl.SSLContext;
 import de.tudarmstadt.informatik.hostage.HoneyService;
 
 /**
- * HTTPS protocol
+ * HTTPS protocol. Extends HTTP.
+ * 
  * @author Wulf Pfeiffer
  */
 public class HTTPS extends HTTP implements SSLProtocol {
@@ -17,40 +18,42 @@ public class HTTPS extends HTTP implements SSLProtocol {
 	public int getDefaultPort() {
 		return 443;
 	}
-	
+
 	@Override
 	public boolean isSecure() {
 		return true;
 	}
-	
+
 	@Override
 	public String toString() {
 		return "HTTPS";
 	}
-	
+
 	@Override
 	public SSLContext getSSLContext() {
-		String ksName = "https_cert.bks";
-		char ksPass[] = "password".toCharArray();
-		KeyStore ks;
-		KeyManagerFactory kmf = null;
+		String keyStoreName = "https_cert.bks";
+		char keyStorePassword[] = "password".toCharArray();
+		KeyStore keyStore;
+		KeyManagerFactory keyManagerFactory = null;
 		try {
-			ks = KeyStore.getInstance(KeyStore.getDefaultType());
-			ks.load(HoneyService.getContext().getAssets().open(ksName), ksPass);
-			kmf = KeyManagerFactory.getInstance(KeyManagerFactory
+			keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+			keyStore.load(
+					HoneyService.getContext().getAssets().open(keyStoreName),
+					keyStorePassword);
+			keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory
 					.getDefaultAlgorithm());
-			kmf.init(ks, ksPass);
+			keyManagerFactory.init(keyStore, keyStorePassword);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-		SSLContext sslcontext = null;
+		SSLContext sslContext = null;
 		try {
-			sslcontext = SSLContext.getInstance("SSLv3");
-			sslcontext.init(kmf.getKeyManagers(), null, null);
+			sslContext = SSLContext.getInstance("SSLv3");
+			sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-		return sslcontext;
+		return sslContext;
 	}
-	
+
 }

+ 83 - 67
src/de/tudarmstadt/informatik/hostage/protocol/MySQL.java

@@ -9,7 +9,8 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * MySQL protocol
+ * MySQL protocol.
+ * 
  * @author Wulf Pfeiffer
  */
 public class MySQL implements Protocol {
@@ -19,69 +20,69 @@ public class MySQL implements Protocol {
 	private enum STATE {
 		NONE, CONNECTED, LOGIN_INFO, CLOSED
 	}
-	
+
 	/**
 	 * Denotes in which state the protocol is right now
 	 */
 	private STATE state = STATE.NONE;
-		
-	/** last request from client */ 
-	private byte[] lastMessage;
-	
+
+	/** last request from client */
+	private byte[] lastReceivedMessage;
+
 	@Override
-	public List<Packet> processMessage(Packet packet) {
+	public List<Packet> processMessage(Packet requestPacket) {
 		byte[] request = null;
-		if (packet != null) {
-			request = packet.getMessage();
+		if (requestPacket != null) {
+			request = requestPacket.getMessage();
 		}
-		List<Packet> response = new ArrayList<Packet>();
-		if(request != null)
-			lastMessage = request;
-				
-		switch(state) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
+		if (request != null)
+			lastReceivedMessage = request;
+
+		switch (state) {
 		case NONE:
-			response.add(greeting());
+			responsePackets.add(greeting());
 			state = STATE.CONNECTED;
 			break;
 		case CONNECTED:
-			response.add(responseOK());
+			responsePackets.add(responseOK());
 			state = STATE.LOGIN_INFO;
 			break;
 		case LOGIN_INFO:
-			if(this.lastMessage[4] == 0x01) {
+			if (this.lastReceivedMessage[4] == 0x01) {
 				state = STATE.CLOSED;
 			} else {
-				response.add(responseError());
+				responsePackets.add(responseError());
 			}
 			break;
 		default:
 			state = STATE.CLOSED;
 			break;
 		}
-		
-		return response;
+
+		return responsePackets;
 	}
-	
+
 	@Override
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.SERVER;
 	}
 
 	@Override
-	public String toString(){
-		return "MySQL";		
+	public String toString() {
+		return "MySQL";
 	}
-	
+
 	@Override
 	public int getDefaultPort() {
 		return 3306;
 	}
-	
+
 	@Override
 	public boolean isClosed() {
 		return state == STATE.CLOSED;
 	}
-	
+
 	@Override
 	public boolean isSecure() {
 		return false;
@@ -94,82 +95,97 @@ public class MySQL implements Protocol {
 
 	/**
 	 * Wraps the response packet with the packet length and number
-	 * @param packet that is wrapped
+	 * 
+	 * @param response
+	 *            that is wrapped
 	 * @return wrapped packet
 	 */
-	private Packet wrapPacket(byte[] packet) {
-		byte[] buffer = ByteBuffer.allocate(4).putInt(packet.length).array();
-		byte[] packetLength = {buffer[3], buffer[2], buffer[1]};
+	private Packet wrapPacket(byte[] response) {
+		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();
+		byte[] packetLength = { buffer[3], buffer[2], buffer[1] };
 		byte[] packetNumber = new byte[1];
-		if(lastMessage != null) packetNumber[0] = (byte) (lastMessage[3] + 1);
-		else packetNumber[0] = 0x00;
-		
-		byte[] response = HelperUtils.concat(packetLength, packetNumber, packet);
-		return new Packet(response);
+		if (lastReceivedMessage != null)
+			packetNumber[0] = (byte) (lastReceivedMessage[3] + 1);
+		else
+			packetNumber[0] = 0x00;
+
+		byte[] wrappedResponse = HelperUtils.concat(packetLength, packetNumber,
+				response);
+		return new Packet(wrappedResponse);
 	}
-	
+
 	/**
 	 * Builds the greeting packet that the server sends as first packet
+	 * 
 	 * @return greeting packet
 	 */
 	private Packet greeting() {
-		byte[] protocol = {0x0a};
+		byte[] protocol = { 0x0a };
 		byte[] version = serverVersion.getBytes();
-		byte[] versionFin = {0x00};
-		byte[] thread = {0x2a, 0x00, 0x00, 0x00};
-		byte[] salt = {0x44, 0x64, 0x49, 0x7e, 0x60, 0x48, 0x25, 0x7e, 0x00};
-		byte[] capabilities = {(byte) 0xff, (byte) 0xf7};
-		byte[] language = {0x08};
-		byte[] status = {0x02, 0x00};
-		byte[] unused = {0x0f, (byte) 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-		byte[] salt2 = {0x6c, 0x26, 0x71, 0x2c, 0x25, 0x72, 0x31, 0x3d, 0x7d, 0x21, 0x26, 0x3b, 0x00};
+		byte[] versionFin = { 0x00 };
+		byte[] thread = { 0x2a, 0x00, 0x00, 0x00 };
+		byte[] salt = { 0x44, 0x64, 0x49, 0x7e, 0x60, 0x48, 0x25, 0x7e, 0x00 };
+		byte[] capabilities = { (byte) 0xff, (byte) 0xf7 };
+		byte[] language = { 0x08 };
+		byte[] status = { 0x02, 0x00 };
+		byte[] unused = { 0x0f, (byte) 0x80, 0x15, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		byte[] salt2 = { 0x6c, 0x26, 0x71, 0x2c, 0x25, 0x72, 0x31, 0x3d, 0x7d,
+				0x21, 0x26, 0x3b, 0x00 };
 		String payload = "mysql_native_password";
-		byte[] fin = {0x00};
-		
-		byte[] response = HelperUtils.concat(protocol, version,versionFin, thread, salt, capabilities, language, status, unused, salt2, payload.getBytes(), fin);
+		byte[] fin = { 0x00 };
+
+		byte[] response = HelperUtils.concat(protocol, version, versionFin,
+				thread, salt, capabilities, language, status, unused, salt2,
+				payload.getBytes(), fin);
 		return wrapPacket(response);
 	}
-	
+
 	/**
 	 * Builds the ok-response packet
+	 * 
 	 * @return ok-response packet
 	 */
 	private Packet responseOK() {
-		byte[] affectedRows = {0x00, 0x00, 0x00};
-		byte[] status = {0x02, 0x00};
-		byte[] warnings = {0x00, 0x00};
-		
+		byte[] affectedRows = { 0x00, 0x00, 0x00 };
+		byte[] status = { 0x02, 0x00 };
+		byte[] warnings = { 0x00, 0x00 };
+
 		byte[] response = HelperUtils.concat(affectedRows, status, warnings);
 		return wrapPacket(response);
 	}
-		
+
 	/**
 	 * Builds the error-response packet
+	 * 
 	 * @return error-response packet
 	 */
 	private Packet responseError() {
-		byte[] fill1 = {(byte) 0xff};
-		byte[] code = {0x17, 0x04};
-		byte[] fill2 = {0x23};
+		byte[] fill1 = { (byte) 0xff };
+		byte[] code = { 0x17, 0x04 };
+		byte[] fill2 = { 0x23 };
 		String state = "08S01";
 		String msg = "Unknown command";
-		
-		byte[] response = HelperUtils.concat(fill1, code, fill2, state.getBytes(), msg.getBytes());		
+
+		byte[] response = HelperUtils.concat(fill1, code, fill2,
+				state.getBytes(), msg.getBytes());
 		return wrapPacket(response);
 	}
-	
-	//version stuff
+
+	// version stuff
 	private static String[][][] possibleMysqlVersions = {
-		{{"5.7."},{"1","2"}},
-		{{"5.6."},{"2","3","4","5","6","7","8","9","10","11","12","13","14"}},
-		{{"5.5."},{"27","28","29","30","31","32","33","34"}}
+	 {{"5.7."},{"1","2"}},
+	 {{"5.6."},{"2","3","4","5","6","7","8","9","10","11","12","13","14"}},
+	 {{"5.5."},{"27","28","29","30","31","32","33","34"}}
 	};
-	
+
 	private static String initMysqlVersion() {
 		SecureRandom rndm = new SecureRandom();
 		int majorVersion = rndm.nextInt(possibleMysqlVersions.length);
-		return possibleMysqlVersions[majorVersion][0][0] + possibleMysqlVersions[majorVersion][1][rndm.nextInt(possibleMysqlVersions[majorVersion][1].length)];
+		return possibleMysqlVersions[majorVersion][0][0]
+				+ possibleMysqlVersions[majorVersion][1][rndm
+						.nextInt(possibleMysqlVersions[majorVersion][1].length)];
 	}
-	
+
 	private static String serverVersion = initMysqlVersion();
 }

+ 555 - 560
src/de/tudarmstadt/informatik/hostage/protocol/SMB.java

@@ -14,7 +14,10 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * SMB protocol
+ * SMB protocol.
+ * It can handle the following requests: Negotiate Protocol Request, Session Setup AndX Request, 
+ * Tree Connect AndX Request, NT Create AndX Request, Bind, NetShareEnumAll, Close Request, 
+ * Tree Disconnect Request, Echo Request, Trans2 Request.
  * @author Wulf Pfeiffer
  */
 public class SMB implements Protocol {
@@ -42,80 +45,78 @@ public class SMB implements Protocol {
 		return TALK_FIRST.CLIENT;
 	}
 	
-	private SMBPacket smbPacket = new SMBPacket();
-
 	@Override
-	public List<Packet> processMessage(Packet packet) {
-		if(packet != null)
-			lastMessage = packet.getMessage();
-		smbPacket.newMsg(lastMessage);
-		byte smbCommand = smbPacket.getSmbCommand();
-		List<Packet> response = new ArrayList<Packet>();
+	public List<Packet> processMessage(Packet requestPacket) {
+		if(requestPacket != null)
+			lastMessage = requestPacket.getMessage();
+		parseMessageHeader(lastMessage);
+		byte smbCommand = getSmbCommand();
+		List<Packet> responsePackets = new ArrayList<Packet>();
 
 		switch (state) {
 		case NONE:
-			if (smbCommand == 0x72) {
+			if (smbCommand == SMB_COM_NEGOTIATE) {
 				state = STATE.CONNECTED;
-				response.add(smbPacket.getNego());
+				responsePackets.add(getNego());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(smbPacket.getTreeDisc());
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case CONNECTED:
-			if (smbCommand == 0x73) {
-				response.add(smbPacket.getSessSetup());
-			} else if (smbCommand == 0x75) {
+			if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
+				responsePackets.add(getSessSetup());
+			} else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
 				state = STATE.AUTHENTICATED;
-				response.add(smbPacket.getTreeCon());
+				responsePackets.add(getTreeCon());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(smbPacket.getTreeDisc());
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case AUTHENTICATED:
-			if (smbCommand == (byte) 0xa2) {
+			if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
 				state = STATE.LISTING;
-				response.add(smbPacket.getNTCreate());
-			} else if (smbCommand == 0x2b) {
-				response.add(smbPacket.getEcho());
-			} else if (smbCommand == 0x32) {
-				response.add(smbPacket.getTrans2());
-			} else if (smbCommand == 0x04) {
-				response.add(smbPacket.getClose());
-			} else if (smbCommand == 0x71) {
+				responsePackets.add(getNTCreate());
+			} else if (smbCommand == SMB_COM_ECHO) {
+				responsePackets.add(getEcho());
+			} else if (smbCommand == SMB_COM_TRANSACTION2) {
+				responsePackets.add(getTrans2());
+			} else if (smbCommand == SMB_COM_CLOSE) {
+				responsePackets.add(getClose());
+			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
 				state = STATE.CLOSED;
-				response.add(smbPacket.getTreeDisc());
+				responsePackets.add(getTreeDisc());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(smbPacket.getTreeDisc());
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case LISTING:
-			if (smbCommand == 0x25) {
-				response.add(smbPacket.getTrans());
-			} else if (smbCommand == 0x04) {
-				response.add(smbPacket.getClose());
-			} else if (smbCommand == 0x71) {
+			if (smbCommand == SMB_COM_TRANSACTION) {
+				responsePackets.add(getTrans());
+			} else if (smbCommand == SMB_COM_CLOSE) {
+				responsePackets.add(getClose());
+			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
 				state = STATE.CLOSED;
-				response.add(smbPacket.getTreeDisc());
-			} else if (smbCommand == 0x72) {
+				responsePackets.add(getTreeDisc());
+			} else if (smbCommand == SMB_COM_NEGOTIATE) {
 				state = STATE.CONNECTED;
-				response.add(smbPacket.getNego());
+				responsePackets.add(getNego());
 			} else {
 				state = STATE.DISCONNECTED;
-				response.add(smbPacket.getTreeDisc());
+				responsePackets.add(getTreeDisc());
 			}
 			break;
 		case DISCONNECTED:
 			state = STATE.CLOSED;
-			response.add(smbPacket.getTreeDisc());
+			responsePackets.add(getTreeDisc());
 			break;
 		default:
 			state = STATE.CLOSED;
-			response.add(smbPacket.getTreeDisc());
+			responsePackets.add(getTreeDisc());
 		}
-		return response;
+		return responsePackets;
 	}
 
 	@Override
@@ -150,14 +151,14 @@ public class SMB implements Protocol {
 		time -= calend.getTimeInMillis();
 		time *= 10000;
 
-		byte[] b = new byte[8];
-		byte[] b2 = ByteBuffer.allocate(8).putLong(time).array();
+		byte[] timeInWindowsBytes = new byte[8];
+		byte[] timeInBytes = ByteBuffer.allocate(8).putLong(time).array();
 
 		for (int i = 0, j = 7; i < 8 && j > -1; i++, j--) {
-			b[i] = (byte) (b2[j] & 0xff);
+			timeInWindowsBytes[i] = (byte) (timeInBytes[j] & 0xff);
 		}
 
-		return b;
+		return timeInWindowsBytes;
 	}
 	
 	/**
@@ -189,551 +190,545 @@ public class SMB implements Protocol {
 		return timezoneBytes;
 	}
 
+	//version stuff
+	private static String[][] possibleSmbVersions = {
+		{"Windows 7 Professional 7600","Windows 7 Professional 6.1"},
+		{"Windows 8 Enterprise 9200", "Windows 8 Enterprise 9200"},
+		{"Windows Server 2008 R2 Enterprise 7600","Windows Server 2008 R2 Enterprise 6.1"},
+		{"Windows Server 2012 Standard 6.2", "Windows Server 2012 Standard 6.2"},
+		{"Unix", "Samba"}
+	};
+	private static String[] initServerVersion() {
+		SharedPreferences sharedPref = HoneyService.getContext().getSharedPreferences("de.tudarmstadt.informatik.hostage.profile", HoneyService.MODE_PRIVATE);
+		String profile = sharedPref.getString("profile", "");
+		System.out.println(profile);
+		if(profile.equals("Windows 7")) {
+			return possibleSmbVersions[0];
+		} else if(profile.equals("Windows 8")) {
+			return possibleSmbVersions[1];
+		} else if(profile.equals("Windows Server 2008")) {
+			return possibleSmbVersions[2];
+		} else if(profile.equals("Windows Server 2012")) {
+			return possibleSmbVersions[3];
+		} else if(profile.equals("Linux")) {
+			return possibleSmbVersions[4];
+		} else {
+			return possibleSmbVersions[new SecureRandom().nextInt(possibleSmbVersions.length)];
+		}
+	}
+	
+	private static byte[] serverName		= HelperUtils.fillWithZero(HelperUtils.getRandomString(16, true).getBytes());
+	private static String[] serverVersion	= initServerVersion();
+		
+	private byte[] message						= null; 
+	private static final byte[] serverGUID		= HelperUtils.randomBytes(16);
+	private boolean authenticateNext			= false;
+	//components of a SMB packet
+	private byte[] serverComp 		= new byte[4];
+	private byte[] smbCommand		= new byte[1];
+	private byte[] ntStat 			= new byte[4];
+	private byte[] smbFlags			= new byte[1];	
+	private byte[] smbFlags2		= new byte[2];
+	private byte[] processIDHigh	= new byte[2];
+	private byte[] signature	 	= new byte[8];
+	private byte[] reserved			= new byte[2];
+	private byte[] treeID			= new byte[2];
+	private byte[] processID		= new byte[2];
+	private byte[] userID			= new byte[2];
+	private byte[] multiplexID		= new byte[2];
+
 	/**
-	 * Denotes a SMB packet
+	 * Breaks a message from the client down into its components
+	 * @param message that is analyzed
 	 */
-	private static class SMBPacket {
-		//version stuff
-		private static String[][] possibleSmbVersions = {
-			{"Windows 7 Professional 7600","Windows 7 Professional 6.1"},
-			{"Windows 8 Enterprise 9200", "Windows 8 Enterprise 9200"},
-			{"Windows Server 2008 R2 Enterprise 7600","Windows Server 2008 R2 Enterprise 6.1"},
-			{"Windows Server 2012 Standard 6.2", "Windows Server 2012 Standard 6.2"},
-			{"Unix", "Samba"}
-		};
-		private static String[] initServerVersion() {
-			SharedPreferences sharedPref = HoneyService.getContext().getSharedPreferences("de.tudarmstadt.informatik.hostage.profile", HoneyService.MODE_PRIVATE);
-			String profile = sharedPref.getString("profile", "");
-			System.out.println(profile);
-			if(profile.equals("Windows 7")) {
-				return possibleSmbVersions[0];
-			} else if(profile.equals("Windows 8")) {
-				return possibleSmbVersions[1];
-			} else if(profile.equals("Windows Server 2008")) {
-				return possibleSmbVersions[2];
-			} else if(profile.equals("Windows Server 2012")) {
-				return possibleSmbVersions[3];
-			} else if(profile.equals("Linux")) {
-				return possibleSmbVersions[4];
-			} else {
-				return possibleSmbVersions[new SecureRandom().nextInt(possibleSmbVersions.length)];
-			}
-		}
-		private static byte[] serverName		= HelperUtils.fillWithZero(HelperUtils.getRandomString(16, true).getBytes());
-		private static String[] serverVersion	= initServerVersion();
+	private void parseMessageHeader(byte[] message) {
+		this.message 	= message;
+		serverComp 		= new byte[]{message[4], message[5], message[6], message[7]};
+		smbCommand		= new byte[]{message[8]};
+		ntStat 			= new byte[]{message[9], message[10], message[11], message[12]};
+		smbFlags		= new byte[]{(byte) (message[13] | 0x80)};		// | 0x80 for mark response bit
+		smbFlags2		= new byte[]{message[14], message[15]};
+		processIDHigh	= new byte[]{message[16], message[17]};
+		signature	 	= new byte[]{message[18], message[19], message[20], message[21], message[22], message[23], message[24], message[25]};
+		reserved		= new byte[]{message[26], message[27]};
+		treeID			= new byte[]{message[28], message[29]};
+		processID		= new byte[]{message[30], message[31]};
+		userID			= new byte[]{message[32], message[33]};
+		multiplexID		= new byte[]{message[34], message[35]};
+	}
+	
+	/**
+	 * Wraps the Netbios header around a response
+	 * @param response that is wrapped
+	 * @return wrapped response
+	 */
+	private byte[] wrapNetbios(byte[] response) {
+		byte[] netbios = {0x00};
+		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();	// allocate(4) because int is 4 bytes long
+		byte[] netbiosLength = {buffer[1], buffer[2], buffer[3]};			// only bytes 1-3 needed, byte 0 is not needed
+		return HelperUtils.concat(netbios, netbiosLength, response);
+	}
+	
+	/**
+	 * Wraps the header around a response
+	 * @param response that is wrapped
+	 * @return wrapped response
+	 */
+	private byte[] wrapHeader(byte[] response) {
+		byte[] header = new byte[0];
+		return HelperUtils.concat(header, serverComp, smbCommand, ntStat, smbFlags, smbFlags2, processIDHigh, signature,
+								reserved, treeID, processID, userID, multiplexID, response);
+	}
+	
+	/**
+	 * Builds the negotiate packet
+	 * @return negotiate packet
+	 */
+	private Packet getNego() {
+		byte[] wordCount	= {0x11};
+		byte[] dialect		= evaluateDialect();		
+		byte[] secMode		= {0x03};
+		byte[] maxMpxC 		= {0x32, 0x00};
+		byte[] maxVcs		= {0x01, 0x00};
+		byte[] maxBufSize	= {0x04, 0x11, 0x00, 0x00};
+		byte[] maxRawBuf	= {0x00, 0x00, 0x01, 0x00};
+		byte[] sessionKey	= {0x00, 0x00, 0x00, 0x00};
+		byte[] capabilities	= {(byte) 0xfc, (byte) 0xe3, 0x01, (byte) 0x80};
+		byte[] sysTime		= getTimeInBytes();
+		byte[] timeZone		= getTimeZoneInBytes();
+		byte[] keyLength	= {0x00};
+		byte[] byteCount	= {0x3a, 0x00};			
+		byte[] guid			= serverGUID;
+		byte[] secBlob		= {0x60, 0x28, 0x06, 0x06};
+		byte[] oid			= {0x2b, 0x06, 0x01, 0x05, 0x05, 0x02};
+		byte[] protectNeg	= {(byte) 0xa0, 0x1e};
+		byte[] negToken		= {0x30, 0x1c, (byte) 0xa0, 0x1a, 0x30, 0x18};
+		byte[] mechType		= {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x1e};
+		byte[] mechType2	= {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x0a};
 		
-		private byte[] message						= null; 
-		private static final byte[] serverGUID		= HelperUtils.randomBytes(16);
-		private boolean authenticateNext			= false;
-		//components of a SMB packet
-		private byte[] serverComp 		= new byte[4];
-		private byte[] smbCommand		= new byte[1];
-		private byte[] ntStat 			= new byte[4];
-		private byte[] smbFlags			= new byte[1];	
-		private byte[] smbFlags2		= new byte[2];
-		private byte[] processIDHigh	= new byte[2];
-		private byte[] signature	 	= new byte[8];
-		private byte[] reserved			= new byte[2];
-		private byte[] treeID			= new byte[2];
-		private byte[] processID		= new byte[2];
-		private byte[] userID			= new byte[2];
-		private byte[] multiplexID		= new byte[2];
-				
-		/** Constructor */
-		private SMBPacket() {
-			
+		byte[] response = HelperUtils.concat(wordCount, dialect, secMode, maxMpxC, maxVcs, maxBufSize, maxRawBuf,
+						sessionKey, capabilities, sysTime, timeZone, keyLength, byteCount, guid, secBlob, oid,
+						protectNeg, negToken, mechType, mechType2);
+		return new Packet(wrapNetbios(wrapHeader(response)));
+	}
+	
+	/**
+	 * Evaluates what Dialects are offered by the client and which position the used NT LM 0.12 dialect is at
+	 * @return position of the NT LM 0.12 dialect
+	 */
+	private byte[] evaluateDialect() {
+		byte[] dialectMsg = new byte[message.length-39];
+		System.arraycopy(message, 39, dialectMsg, 0, message.length - 39);
+		short dialectNumber = 0;
+		for(int i = 0, start = 0; i < dialectMsg.length; i++) {
+			if(dialectMsg[i] == 0x00) {
+				byte[] dialect = new byte[i-start];
+				System.arraycopy(dialectMsg, start, dialect, 0, i-start);
+				if(HelperUtils.byteToStr(dialect).contains("NT LM 0.12")) {
+					return new byte[]{(byte)dialectNumber, (byte)(dialectNumber >> 8)};
+				}
+				start = i+1;
+				dialectNumber++;
+			}
 		}
-		
-		/**
-		 * Breaks a message from the client down into its components
-		 * @param message that is analyzed
-		 */
-		private void newMsg(byte[] message) {
-			this.message 	= message;
-			serverComp 		= new byte[]{message[4], message[5], message[6], message[7]};
-			smbCommand		= new byte[]{message[8]};
-			ntStat 			= new byte[]{message[9], message[10], message[11], message[12]};
-			smbFlags		= new byte[]{(byte) (message[13] | 0x80)};		// | 0x80 for mark response bit
-			smbFlags2		= new byte[]{message[14], message[15]};
-			processIDHigh	= new byte[]{message[16], message[17]};
-			signature	 	= new byte[]{message[18], message[19], message[20], message[21], message[22], message[23], message[24], message[25]};
-			reserved		= new byte[]{message[26], message[27]};
-			treeID			= new byte[]{message[28], message[29]};
-			processID		= new byte[]{message[30], message[31]};
-			userID			= new byte[]{message[32], message[33]};
-			multiplexID		= new byte[]{message[34], message[35]};
+		return new byte[]{0x00, 0x00};
+	}
+	
+	/**
+	 * Builds the session setup packet
+	 * @ret	urn session setup packet
+	 */
+	private Packet getSessSetup() {
+		if(authenticateNext) {
+			return new Packet(getSetupAuth());
+		} else {
+			authenticateNext = true;
+			return new Packet(getSetupChal());
 		}
-		
-		/**
-		 * Wraps the Netbios header around a response
-		 * @param response that is wrapped
-		 * @return wrapped response
-		 */
-		private byte[] wrapNetbios(byte[] response) {
-			byte[] netbios = {0x00};
-			byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();	// allocate(4) because int is 4 bytes long
-			byte[] netbiosLength = {buffer[1], buffer[2], buffer[3]};			// only bytes 1-3 needed, byte 0 is not needed
-			return HelperUtils.concat(netbios, netbiosLength, response);
+	}
+	
+	/**
+	 * Builds the session setup challange packet
+	 * @return session setup challange packet
+	 */
+	private byte[] getSetupChal() {
+		byte[] wordCount			= {0x04};
+		byte[] andXCommand			= {(byte) 0xff};
+		byte[] reserved				= {0x00};
+		byte[] andXOffset			= {0x60, 0x01};
+		byte[] action				= {0x00, 0x00};
+		byte[] secBlobLength;
+		byte[] byteCount;
+		byte[] secBlob				= {(byte) 0xa1, (byte) 0x81, (byte) 0xc4};
+		byte[] negToken				= {0x30, (byte) 0x81, (byte) 0xc1, (byte) 0xa0, 0x03, 0x0a, 0x01};
+		byte[] negResult			= {0x01};
+		byte[] negToken2			= {(byte) 0xa1, 0x0c, 0x06, 0x0a};
+		byte[] supportedMech		= {0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x0a};
+		byte[] negToken3			= {(byte) 0xa2, (byte) 0x81, (byte) 0xab, 0x04, (byte) 0x81, (byte) 0xa8};
+		byte[] ntlmsspId			= {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00};
+		byte[] nlmMsgType			= {0x02, 0x00, 0x00, 0x00};
+		byte[] buffer				= ByteBuffer.allocate(4).putInt(serverName.length).array();
+		byte[] targetNameLength		= new byte[]{buffer[3], buffer[2]};
+		byte[] targetNameMaxLength	= new byte[]{buffer[3], buffer[2]}; 
+		byte[] targetNameOffset		= {0x38, 0x00, 0x00, 0x00};
+		byte[] flags				= {0x15, (byte) 0x82, (byte) 0x8a, 0x60};
+		if(!serverVersion[0].contains("Unix")) {
+			flags[3] = (byte) (flags[3] | 0x02);
 		}
-		
-		/**
-		 * Wraps the header around a response
-		 * @param response that is wrapped
-		 * @return wrapped response
-		 */
-		private byte[] wrapHeader(byte[] response) {
-			byte[] header = new byte[0];
-			return HelperUtils.concat(header, serverComp, smbCommand, ntStat, smbFlags, smbFlags2, processIDHigh, signature,
-									reserved, treeID, processID, userID, multiplexID, response);
+		byte[] challenge			= HelperUtils.randomBytes(8);
+		byte[] reserved2			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] targetInfoLength		= {0x60, 0x00};
+		byte[] targetInfoMaxLength	= {0x60, 0x00};
+		byte[] targetInfoOffset		= {0x48, 0x00, 0x00, 0x00};
+		byte[] version = null;
+		if(serverVersion[0].contains("Windows 7") || serverVersion[0].contains("Windows Server 2008")) {
+			version = new byte[]{0x06, 0x01, (byte) 0xb0, 0x1d, 0x00, 0x00, 0x00, 0x0f};
+		} else if(serverVersion[0].contains("Windows 8") || serverVersion[0].contains("Windows Server 2012")) {
+			version = new byte[]{0x06, 0x02, (byte) 0xf0, 0x23, 0x00, 0x00, 0x00, 0x0f};
 		}
+		// serverName
+		byte[] attributeNBDomain	= {0x02, 0x00, 0x10, 0x00};
+		// serverName	
+		byte[] attributeNBcomputer	= {0x01, 0x00, 0x10, 0x00};
+		// serverName	
+		byte[] attributeDNSDomain	= {0x04, 0x00, 0x10, 0x00};
+		// serverName
+		byte[] attributeDNScomputer	= {0x03, 0x00, 0x10, 0x00};
+		// serverName
+		byte[] attributeTimeStamp   = {0x07, 0x00, 0x08, 0x00};
+		byte[] timeStamp = getTimeInBytes();
+		byte[] attributeEnd			= {0x00, 0x00, 0x00, 0x00};
+		secBlob						= HelperUtils.concat(secBlob, negToken, negResult, negToken2, supportedMech, negToken3,
+											ntlmsspId, nlmMsgType, targetNameLength, targetNameMaxLength, targetNameOffset,
+											flags, challenge, reserved2, targetInfoLength, targetInfoMaxLength, targetInfoOffset,
+											version, serverName, attributeNBDomain, serverName, attributeNBcomputer, serverName,
+											attributeDNSDomain, serverName, attributeDNScomputer, serverName, attributeTimeStamp,
+											timeStamp, attributeEnd);
+		byte[] nativOS				= HelperUtils.fillWithZeroExtended(serverVersion[0].getBytes());
+		byte[] nativLanMngr			= HelperUtils.fillWithZeroExtended(serverVersion[1].getBytes());
+		buffer						= ByteBuffer.allocate(4).putInt(secBlob.length).array();
+		secBlobLength				= new byte[]{buffer[3], buffer[2]};
+		buffer						= ByteBuffer.allocate(4).putInt(secBlob.length + nativOS.length + nativLanMngr.length).array();
+		byteCount					= new byte[]{buffer[3], buffer[2]};
 		
-		/**
-		 * Builds the negotiate packet
-		 * @return negotiate packet
-		 */
-		private Packet getNego() {
-			byte[] wordCount	= {0x11};
-			byte[] dialect		= evaluateDialect();		
-			byte[] secMode		= {0x03};
-			byte[] maxMpxC 		= {0x32, 0x00};
-			byte[] maxVcs		= {0x01, 0x00};
-			byte[] maxBufSize	= {0x04, 0x11, 0x00, 0x00};
-			byte[] maxRawBuf	= {0x00, 0x00, 0x01, 0x00};
-			byte[] sessionKey	= {0x00, 0x00, 0x00, 0x00};
-			byte[] capabilities	= {(byte) 0xfc, (byte) 0xe3, 0x01, (byte) 0x80};
-			byte[] sysTime		= getTimeInBytes();
-			byte[] timeZone		= getTimeZoneInBytes();
-			byte[] keyLength	= {0x00};
-			byte[] byteCount	= {0x3a, 0x00};			
-			byte[] guid			= serverGUID;
-			byte[] secBlob		= {0x60, 0x28, 0x06, 0x06};
-			byte[] oid			= {0x2b, 0x06, 0x01, 0x05, 0x05, 0x02};
-			byte[] protectNeg	= {(byte) 0xa0, 0x1e};
-			byte[] negToken		= {0x30, 0x1c, (byte) 0xa0, 0x1a, 0x30, 0x18};
-			byte[] mechType		= {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x1e};
-			byte[] mechType2	= {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x0a};
-			
-			byte[] response = HelperUtils.concat(wordCount, dialect, secMode, maxMpxC, maxVcs, maxBufSize, maxRawBuf,
-							sessionKey, capabilities, sysTime, timeZone, keyLength, byteCount, guid, secBlob, oid,
-							protectNeg, negToken, mechType, mechType2);
-			return new Packet(wrapNetbios(wrapHeader(response)));
-		}
+		ntStat 					= new byte[]{0x16, 0x00, 0x00, (byte) 0xc0};
+		userID					= new byte[]{0x00, 0x08};
 		
-		/**
-		 * Evaluates what Dialects are offered by the client and which position the used NT LM 0.12 dialect is at
-		 * @return position of the NT LM 0.12 dialect
-		 */
-		private byte[] evaluateDialect() {
-			byte[] dialectMsg = new byte[message.length-39];
-			System.arraycopy(message, 39, dialectMsg, 0, message.length - 39);
-			short dialectNumber = 0;
-			for(int i = 0, start = 0; i < dialectMsg.length; i++) {
-				if(dialectMsg[i] == 0x00) {
-					byte[] dialect = new byte[i-start];
-					System.arraycopy(dialectMsg, start, dialect, 0, i-start);
-					if(HelperUtils.byteToStr(dialect).contains("NT LM 0.12")) {
-						return new byte[]{(byte)dialectNumber, (byte)(dialectNumber >> 8)};
-					}
-					start = i+1;
-					dialectNumber++;
-				}
-			}
-			return new byte[]{0x00, 0x00};
-		}
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
+											byteCount, secBlob, nativOS, nativLanMngr);
+		return wrapNetbios(wrapHeader(response));
+	}
+	
+	/**
+	 * Builds the session setup packet for authentication required
+	 * @return session setup authentication packet
+	 */
+	private byte[] getSetupAuth() {
+		byte[] wordCount		= {0x04};
+		byte[] andXCommand		= {(byte) 0xff};
+		byte[] reserved			= {0x00};
+		byte[] andXOffset		= {(byte) 0xa2, 0x00};
+		byte[] action			= {0x01, 0x00};
+		byte[] secBlobLength;
+		byte[] byteCount;
+		byte[] secBlob			= {(byte) 0xa1, 0x07, 0x30, 0x05, (byte) 0xa0, 0x03, 0x0a, 0x01, 0x00};
+		byte[] nativOS			= HelperUtils.fillWithZeroExtended(serverVersion[0].getBytes());
+		byte[] nativLanMngr		= HelperUtils.fillWithZeroExtended(serverVersion[1].getBytes());
 		
-		/**
-		 * Builds the session setup packet
-		 * @return session setup packet
-		 */
-		private Packet getSessSetup() {
-			if(authenticateNext) {
-				return new Packet(getSetupAuth());
-			} else {
-				authenticateNext = true;
-				return new Packet(getSetupChal());
-			}
-		}
+		byte[] buffer				= ByteBuffer.allocate(4).putInt(secBlob.length).array();
+		secBlobLength				= new byte[]{buffer[3], buffer[2]};
+		buffer						= ByteBuffer.allocate(4).putInt(secBlob.length + nativOS.length + nativLanMngr.length).array();
+		byteCount					= new byte[]{buffer[3], buffer[2]};
 		
-		/**
-		 * Builds the session setup challange packet
-		 * @return session setup challange packet
-		 */
-		private byte[] getSetupChal() {
-			byte[] wordCount			= {0x04};
-			byte[] andXCommand			= {(byte) 0xff};
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
+				byteCount, secBlob, nativOS, nativLanMngr);
+		return wrapNetbios(wrapHeader(response));
+	}
+	
+	/**
+	 * Builds the tree connect packet
+	 * @return tree connect packet
+	 */
+	private Packet getTreeCon() {
+		String str 			= HelperUtils.byteToStr(message);
+		byte[] wordCount	= {0x00};
+		byte[] andXCommand	= {0x00, 0x00};
+		byte[] response 	= null;
+		if(str.contains("IPC$") || str.contains("C$")) {
+			wordCount			= new byte[] {0x07};
+			andXCommand			= new byte[] {(byte) 0xff};
 			byte[] reserved				= {0x00};
-			byte[] andXOffset			= {0x60, 0x01};
-			byte[] action				= {0x00, 0x00};
-			byte[] secBlobLength;
-			byte[] byteCount;
-			byte[] secBlob				= {(byte) 0xa1, (byte) 0x81, (byte) 0xc4};
-			byte[] negToken				= {0x30, (byte) 0x81, (byte) 0xc1, (byte) 0xa0, 0x03, 0x0a, 0x01};
-			byte[] negResult			= {0x01};
-			byte[] negToken2			= {(byte) 0xa1, 0x0c, 0x06, 0x0a};
-			byte[] supportedMech		= {0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82, 0x37, 0x02, 0x02, 0x0a};
-			byte[] negToken3			= {(byte) 0xa2, (byte) 0x81, (byte) 0xab, 0x04, (byte) 0x81, (byte) 0xa8};
-			byte[] ntlmsspId			= {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00};
-			byte[] nlmMsgType			= {0x02, 0x00, 0x00, 0x00};
-			byte[] buffer				= ByteBuffer.allocate(4).putInt(serverName.length).array();
-			byte[] targetNameLength		= new byte[]{buffer[3], buffer[2]};
-			byte[] targetNameMaxLength	= new byte[]{buffer[3], buffer[2]}; 
-			byte[] targetNameOffset		= {0x38, 0x00, 0x00, 0x00};
-			byte[] flags				= {0x15, (byte) 0x82, (byte) 0x8a, 0x60};
-			if(!serverVersion[0].contains("Unix")) {
-				flags[3] = (byte) (flags[3] | 0x02);
-			}
-			byte[] challenge			= HelperUtils.randomBytes(8);
-			byte[] reserved2			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] targetInfoLength		= {0x60, 0x00};
-			byte[] targetInfoMaxLength	= {0x60, 0x00};
-			byte[] targetInfoOffset		= {0x48, 0x00, 0x00, 0x00};
-			byte[] version = null;
-			if(serverVersion[0].contains("Windows 7") || serverVersion[0].contains("Windows Server 2008")) {
-				version = new byte[]{0x06, 0x01, (byte) 0xb0, 0x1d, 0x00, 0x00, 0x00, 0x0f};
-			} else if(serverVersion[0].contains("Windows 8") || serverVersion[0].contains("Windows Server 2012")) {
-				version = new byte[]{0x06, 0x02, (byte) 0xf0, 0x23, 0x00, 0x00, 0x00, 0x0f};
-			}
-			// serverName
-			byte[] attributeNBDomain	= {0x02, 0x00, 0x10, 0x00};
-			// serverName	
-			byte[] attributeNBcomputer	= {0x01, 0x00, 0x10, 0x00};
-			// serverName	
-			byte[] attributeDNSDomain	= {0x04, 0x00, 0x10, 0x00};
-			// serverName
-			byte[] attributeDNScomputer	= {0x03, 0x00, 0x10, 0x00};
-			// serverName
-			byte[] attributeTimeStamp   = {0x07, 0x00, 0x08, 0x00};
-			byte[] timeStamp = getTimeInBytes();
-			byte[] attributeEnd			= {0x00, 0x00, 0x00, 0x00};
-			secBlob						= HelperUtils.concat(secBlob, negToken, negResult, negToken2, supportedMech, negToken3,
-												ntlmsspId, nlmMsgType, targetNameLength, targetNameMaxLength, targetNameOffset,
-												flags, challenge, reserved2, targetInfoLength, targetInfoMaxLength, targetInfoOffset,
-												version, serverName, attributeNBDomain, serverName, attributeNBcomputer, serverName,
-												attributeDNSDomain, serverName, attributeDNScomputer, serverName, attributeTimeStamp,
-												timeStamp, attributeEnd);
-			byte[] nativOS				= HelperUtils.fillWithZeroExtended(serverVersion[0].getBytes());
-			byte[] nativLanMngr			= HelperUtils.fillWithZeroExtended(serverVersion[1].getBytes());
-
-			buffer				= ByteBuffer.allocate(4).putInt(secBlob.length).array();
-			secBlobLength				= new byte[]{buffer[3], buffer[2]};
-			buffer						= ByteBuffer.allocate(4).putInt(secBlob.length + nativOS.length + nativLanMngr.length).array();
-			byteCount					= new byte[]{buffer[3], buffer[2]};
-			
-			ntStat 					= new byte[]{0x16, 0x00, 0x00, (byte) 0xc0};
-			userID					= new byte[]{0x00, 0x08};
-			
-			byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
-												byteCount, secBlob, nativOS, nativLanMngr);
-			return wrapNetbios(wrapHeader(response));
+			byte[] andXOffset			= {0x38, 0x00};
+			byte[] optionalSupport		= {0x01, 0x00};
+			byte[] maxShareAccess		= {(byte) 0xff, (byte) 0xff, 0x1f, 0x00};
+			byte[] guestMaxShareAccess	= {(byte) 0xff, (byte) 0xff, 0x1f, 0x00};
+			byte[] byteCount			= {0x07, 0x00};
+			byte[] service				= {0x49, 0x50, 0x43, 0x00};
+			byte[] extraParameters		= {0x00, 0x00, 0x00};
+		
+			treeID						= new byte[]{0x00, 0x08};
+						
+			response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, optionalSupport, maxShareAccess,
+											guestMaxShareAccess, byteCount, service, extraParameters);
+		} else if(str.contains("ADMIN$")) {
+			ntStat = new byte[] {0x22, 0x00, 0x00, (byte) 0xc0};
+			response = HelperUtils.concat(wordCount, andXCommand);
+		} else {
+			ntStat = new byte[] {(byte) 0xcc, 0x00, 0x00, (byte) 0xc0};
+			response = HelperUtils.concat(wordCount, andXCommand);
 		}
 		
-		/**
-		 * Builds the session setup packet for authentication required
-		 * @return session setup authentication packet
-		 */
-		private byte[] getSetupAuth() {
-			byte[] wordCount		= {0x04};
-			byte[] andXCommand		= {(byte) 0xff};
-			byte[] reserved			= {0x00};
-			byte[] andXOffset		= {(byte) 0xa2, 0x00};
-			byte[] action			= {0x01, 0x00};
-			byte[] secBlobLength;
-			byte[] byteCount;
-			byte[] secBlob			= {(byte) 0xa1, 0x07, 0x30, 0x05, (byte) 0xa0, 0x03, 0x0a, 0x01, 0x00};
-			byte[] nativOS			= HelperUtils.fillWithZeroExtended(serverVersion[0].getBytes());
-			byte[] nativLanMngr		= HelperUtils.fillWithZeroExtended(serverVersion[1].getBytes());
+		return new Packet(wrapNetbios(wrapHeader(response)));
+	}
+	
+	/**
+	 * Builds the nt create packet
+	 * @return nt create packet
+	 */
+	private Packet getNTCreate() {
+		byte[] wordCount		= {0x22};
+		byte[] andXCommand		= {(byte) 0xff};
+		byte[] reserved			= {0x00};
+		byte[] andXOffset		= {0x67, 0x00};
+		byte[] oplockLevel		= {0x00};
+		byte[] fid				= {(byte) 0x00, 0x40};
+		byte[] createAction		= {0x01, 0x00, 0x00, 0x00};
+		byte[] created			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] lastAccess		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] lastWrite		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] change			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] fileAttributes	= {(byte) 0x80, 0x00, 0x00, 0x00};
+		byte[] allocationSize	= {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] endOfFile		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		byte[] fileType			= {0x02, 0x00};
+		byte[] ipcState			= {(byte) 0xff, 0x05};
+		byte[] isDirectory		= {0x00};
+		byte[] byteCount		= {0x00, 0x00};
+		
+		byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, oplockLevel, fid,
+											createAction, created, lastAccess, lastWrite, change, fileAttributes, allocationSize,
+											endOfFile, fileType, ipcState, isDirectory, byteCount);
+		return new Packet(wrapNetbios(wrapHeader(response)));
+	}
+	
+	/**
+	 * Builds the trans packet
+	 * @return trans packet
+	 */
+	private Packet getTrans() {
+		byte[] transSub	= getTransSub();
+		byte[] response = null;
+		if(transSub[0] == 0x00 && transSub[1] == 0x0b) { //bind_ack
+			byte[] wordCount		= {0x0a};
+			byte[] totalParamCount	= {0x00,0x00};
+			byte[] totalDataCount	= {0x44,0x00};
+			byte[] reserved			= {0x00, 0x00};
+			byte[] paramCount		= {0x00, 0x00};
+			byte[] paramOffset		= {0x38, 0x00};
+			byte[] paramDisplace	= {0x00, 0x00};
+			byte[] dataCount		= {0x44, 0x00};
+			byte[] dataOffset		= {0x38, 0x00};
+			byte[] dataDisplace		= {0x00, 0x00};
+			byte[] setupCount		= {0x00};
+			byte[] reserved2		= {0x00};
+			byte[] byteCount		= {0x45, 0x00};
+			byte[] padding			= {0x00};
 			
-			byte[] buffer				= ByteBuffer.allocate(4).putInt(secBlob.length).array();
-			secBlobLength				= new byte[]{buffer[3], buffer[2]};
-			buffer						= ByteBuffer.allocate(4).putInt(secBlob.length + nativOS.length + nativLanMngr.length).array();
-			byteCount					= new byte[]{buffer[3], buffer[2]};
+			byte[] dcerpc			= getDceRpc(transSub, 0); 
 			
-			byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, action, secBlobLength,
-					byteCount, secBlob, nativOS, nativLanMngr);
-			return wrapNetbios(wrapHeader(response));
-		}
-		
-		/**
-		 * Builds the tree connect packet
-		 * @return tree connect packet
-		 */
-		private Packet getTreeCon() {
-			String str 			= toString();
-			byte[] wordCount	= {0x00};
-			byte[] andXCommand	= {0x00, 0x00};
-			byte[] response 	= null;
-			if(str.contains("IPC$") || str.contains("C$")) {
-				wordCount			= new byte[] {0x07};
-				andXCommand			= new byte[] {(byte) 0xff};
-				byte[] reserved				= {0x00};
-				byte[] andXOffset			= {0x38, 0x00};
-				byte[] optionalSupport		= {0x01, 0x00};
-				byte[] maxShareAccess		= {(byte) 0xff, (byte) 0xff, 0x1f, 0x00};
-				byte[] guestMaxShareAccess	= {(byte) 0xff, (byte) 0xff, 0x1f, 0x00};
-				byte[] byteCount			= {0x07, 0x00};
-				byte[] service				= {0x49, 0x50, 0x43, 0x00};
-				byte[] extraParameters		= {0x00, 0x00, 0x00};
+			response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
+												paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc);
 			
-				treeID						= new byte[]{0x00, 0x08};
-							
-				response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, optionalSupport, maxShareAccess,
-												guestMaxShareAccess, byteCount, service, extraParameters);
-			} else if(str.contains("ADMIN$")) {
-				ntStat = new byte[] {0x22, 0x00, 0x00, (byte) 0xc0};
-				response = HelperUtils.concat(wordCount, andXCommand);
-			} else {
-				ntStat = new byte[] {(byte) 0xcc, 0x00, 0x00, (byte) 0xc0};
-				response = HelperUtils.concat(wordCount, andXCommand);
-			}
+		} else if(transSub[0] == 0x00 && transSub[1] == 0x00) { //netShareEnumAll
+			byte[] wordCount		= {0x0a};
+			byte[] totalParamCount	= {0x00, 0x00};
+			byte[] totalDataCount	= {0x20, 0x01};
+			byte[] reserved			= {0x00, 0x00};
+			byte[] paramCount		= {0x00, 0x00};
+			byte[] paramOffset		= {0x38, 0x00};
+			byte[] paramDisplace	= {0x00, 0x00};
+			byte[] dataCount		= {0x20, 0x01};
+			byte[] dataOffset		= {0x38, 0x00};
+			byte[] dataDisplace		= {0x00, 0x00};
+			byte[] setupCount		= {0x00};
+			byte[] reserved2		= {0x00};
+			byte[] byteCount		= new byte[2]/*= {0x21, 0x01}*/;
+			byte[] padding			= {0x00};
 			
-			return new Packet(wrapNetbios(wrapHeader(response)));
-		}
-		
-		/**
-		 * Builds the nt create packet
-		 * @return nt create packet
-		 */
-		private Packet getNTCreate() {
-			byte[] wordCount		= {0x22};
-			byte[] andXCommand		= {(byte) 0xff};
-			byte[] reserved			= {0x00};
-			byte[] andXOffset		= {0x67, 0x00};
-			byte[] oplockLevel		= {0x00};
-			byte[] fid				= {(byte) 0x00, 0x40};
-			byte[] createAction		= {0x01, 0x00, 0x00, 0x00};
-			byte[] created			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] lastAccess		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] lastWrite		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] change			= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] fileAttributes	= {(byte) 0x80, 0x00, 0x00, 0x00};
-			byte[] allocationSize	= {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] endOfFile		= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-			byte[] fileType			= {0x02, 0x00};
-			byte[] ipcState			= {(byte) 0xff, 0x05};
-			byte[] isDirectory		= {0x00};
-			byte[] byteCount		= {0x00, 0x00};
+			byte[] dcerpc			= new byte[24];
 			
-			byte[] response = HelperUtils.concat(wordCount, andXCommand, reserved, andXOffset, oplockLevel, fid,
-												createAction, created, lastAccess, lastWrite, change, fileAttributes, allocationSize,
-												endOfFile, fileType, ipcState, isDirectory, byteCount);
-			return new Packet(wrapNetbios(wrapHeader(response)));
-		}
-		
-		/**
-		 * Builds the trans packet
-		 * @return trans packet
-		 */
-		private Packet getTrans() {
-			byte[] transSub	= getTransSub();
-			byte[] response = null;
-			if(transSub[0] == 0x00 && transSub[1] == 0x0b) { //bind_ack
-				byte[] wordCount		= {0x0a};
-				byte[] totalParamCount	= {0x00,0x00};
-				byte[] totalDataCount	= {0x44,0x00};
-				byte[] reserved			= {0x00, 0x00};
-				byte[] paramCount		= {0x00, 0x00};
-				byte[] paramOffset		= {0x38, 0x00};
-				byte[] paramDisplace	= {0x00, 0x00};
-				byte[] dataCount		= {0x44, 0x00};
-				byte[] dataOffset		= {0x38, 0x00};
-				byte[] dataDisplace		= {0x00, 0x00};
-				byte[] setupCount		= {0x00};
-				byte[] reserved2		= {0x00};
-				byte[] byteCount		= {0x45, 0x00};
-				byte[] padding			= {0x00};
-				
-				byte[] dcerpc			= getDceRpc(transSub, 0); 
-				
-				response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
-													paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc);
-				
-			} else if(transSub[0] == 0x00 && transSub[1] == 0x00) { //netShareEnumAll
-				byte[] wordCount		= {0x0a};
-				byte[] totalParamCount	= {0x00, 0x00};
-				byte[] totalDataCount	= {0x20, 0x01};
-				byte[] reserved			= {0x00, 0x00};
-				byte[] paramCount		= {0x00, 0x00};
-				byte[] paramOffset		= {0x38, 0x00};
-				byte[] paramDisplace	= {0x00, 0x00};
-				byte[] dataCount		= {0x20, 0x01};
-				byte[] dataOffset		= {0x38, 0x00};
-				byte[] dataDisplace		= {0x00, 0x00};
-				byte[] setupCount		= {0x00};
-				byte[] reserved2		= {0x00};
-				byte[] byteCount		= new byte[2]/*= {0x21, 0x01}*/;
-				byte[] padding			= {0x00};
-				
-				byte[] dcerpc			= new byte[24];
-				
-				byte[] levelPointer		= {0x01, 0x00, 0x00, 0x00};
-				byte[] ctr				= {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
-				byte[] ctr1				= {0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
-				byte[] array1Pointer	= {0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x0c, 0x00, 0x02, 0x00};
-				byte[] array2Pointer	= {0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x14, 0x00, 0x02, 0x00};
-				byte[] array3Pointer	= {0x18, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, (byte) 0x80, 0x1c, 0x00, 0x02, 0x00};
-				byte[] array1			= {0x07, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x44, 0x00, 0x4d, 0x00, 
-											0x49, 0x00, 0x4e, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 
-											0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x74, 0x00, 
-											0x65, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00};
-				byte[] array2			= {0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x43, 0x00, 
-											0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 
-											0x00, 0x00, 0x44, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x74, 0x00, 
-											0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00};
-				byte[] array3			= {0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 
-											0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 
-											0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 
-											0x6f, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00, 0x00, 0x00};
-				byte[] totalEntries		= {0x00, 0x00, 0x03, 0x00, 0x00, 0x00};
-				byte[] referentID		= {0x20, 0x00, 0x02, 0x00};
-				byte[] resumeHandle		= {0x00, 0x00, 0x00, 0x00};
-				byte[] windowsError		= {0x00, 0x00, 0x00, 0x00};
-				int tmp					= padding.length + dcerpc.length + levelPointer.length + ctr.length + ctr1.length
-											+ array1Pointer.length + array2Pointer.length + array3Pointer.length + array1.length
-											+ array2.length + array3.length + totalEntries.length + referentID.length + resumeHandle.length
-											+ windowsError.length;
-				byte[] tmp2				= ByteBuffer.allocate(4).putInt(tmp).array();
-				byteCount				= new byte[] {tmp2[3], tmp2[2]};
-				dcerpc					= getDceRpc(transSub, tmp-1);
+			byte[] levelPointer		= {0x01, 0x00, 0x00, 0x00};
+			byte[] ctr				= {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+			byte[] ctr1				= {0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00};
+			byte[] array1Pointer	= {0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x0c, 0x00, 0x02, 0x00};
+			byte[] array2Pointer	= {0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x14, 0x00, 0x02, 0x00};
+			byte[] array3Pointer	= {0x18, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, (byte) 0x80, 0x1c, 0x00, 0x02, 0x00};
+			byte[] array1			= {0x07, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x44, 0x00, 0x4d, 0x00, 
+										0x49, 0x00, 0x4e, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 
+										0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x74, 0x00, 
+										0x65, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00};
+			byte[] array2			= {0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x43, 0x00, 
+										0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 
+										0x00, 0x00, 0x44, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x74, 0x00, 
+										0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00};
+			byte[] array3			= {0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 
+										0x00, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 
+									0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 
+										0x6f, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49, 0x00, 0x50, 0x00, 0x43, 0x00, 0x00, 0x00};
+			byte[] totalEntries		= {0x00, 0x00, 0x03, 0x00, 0x00, 0x00};
+			byte[] referentID		= {0x20, 0x00, 0x02, 0x00};
+			byte[] resumeHandle		= {0x00, 0x00, 0x00, 0x00};
+			byte[] windowsError		= {0x00, 0x00, 0x00, 0x00};
+			int tmp					= padding.length + dcerpc.length + levelPointer.length + ctr.length + ctr1.length
+										+ array1Pointer.length + array2Pointer.length + array3Pointer.length + array1.length
+										+ array2.length + array3.length + totalEntries.length + referentID.length + resumeHandle.length
+										+ windowsError.length;
+			byte[] tmp2				= ByteBuffer.allocate(4).putInt(tmp).array();
+			byteCount				= new byte[] {tmp2[3], tmp2[2]};
+			dcerpc					= getDceRpc(transSub, tmp-1);
 
-				response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
-												paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc,
-												levelPointer, ctr, ctr1, array1Pointer, array2Pointer, array3Pointer, 
-												array1, array2, array3, totalEntries, referentID, resumeHandle, windowsError);
-				
-				
-			}
-			
-			return new Packet(wrapNetbios(wrapHeader(response)));		
+			response = HelperUtils.concat(wordCount, totalParamCount, totalDataCount, reserved, paramCount, paramOffset,
+											paramDisplace, dataCount, dataOffset, dataDisplace, setupCount, reserved2, byteCount, padding, dcerpc,
+											levelPointer, ctr, ctr1, array1Pointer, array2Pointer, array3Pointer, 
+											array1, array2, array3, totalEntries, referentID, resumeHandle, windowsError);	
 		}
-		
-		/**
-		 * Builds the DCERPC packet
-		 * @return DCERPC packet
-		 */
-		private byte[] getDceRpc(byte[] transSub, int length) {
-			byte[] majorVersion	= {0x05};
-			byte[] minorVersion	= {0x00};
-			byte[] packetType	= null;
-			byte[] packetFlags	= {0x03};
-			byte[] dataRepres	= {0x10, 0x00, 0x00, 0x00};
-			byte[] fragLength	= null;
-			byte[] authLength	= {0x00, 0x00};
-			byte[] callID		= null;
-			byte[] response		= null;
 			
-			if(transSub[0] == 0x00 && transSub[1] == 0x0b) {
-				packetType	= new byte[]{0x0c};
-				fragLength	= new byte[]{0x44, 0x00};
-				callID		= new byte[]{0x01, 0x00, 0x00, 0x00};
-				byte[] maxXmitFrag		= {(byte) 0xb8, 0x10};
-				byte[] maxRecvFrag		= {(byte) 0xb8, 0x10};
-				byte[] assocGroup		= {0x4a, 0x41, 0x00, 0x00};
-				byte[] scndryAddrLen	= {0x0d, 0x00};
-				byte[] scndryAddr		= {0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x73, 0x72, 
-													0x76, 0x73, 0x76, 0x63, 0x00, 0x00};
-				byte[] numResults		= {0x01, 0x00, 0x00, 0x00};
-				byte[] ctxItem			= {0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, (byte) 0x88, (byte) 0x8a,
-													(byte) 0xeb, 0x1c, (byte) 0xc9, 0x11, (byte) 0x9f, (byte) 0xe8,
-													0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,	0x00, 0x00};
-				
-				response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
-						authLength, callID, maxXmitFrag, maxRecvFrag, assocGroup, scndryAddrLen, scndryAddr, numResults, ctxItem);
-			} else if(transSub[0] == 0x00 && transSub[1] == 0x00) {
-				packetType	= new byte[]{0x02};
-				byte[] tmp	= ByteBuffer.allocate(4).putInt(length).array();
-				fragLength	= new byte[]{tmp[3], tmp[2]};
-				callID		= new byte[]{0x02, 0x00, 0x00, 0x00};
-				tmp			= ByteBuffer.allocate(4).putInt(length-24).array();
-				byte[] allocHint	= new byte[]{tmp[3], tmp[2], tmp[1], tmp[0]};
-				byte[] contextID	= {0x00, 0x00};
-				byte[] cancelCount	= {0x00, 0x00};
-				
-				response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
-						authLength, callID, allocHint, contextID, cancelCount);
-			}			
-			return response;
-		}
+		return new Packet(wrapNetbios(wrapHeader(response)));		
+	}
 		
-		/**
-		 * Builds the close packet
-		 * @return close packet
-		 */
-		private Packet getClose() {
-			byte[] wordCount	= {0x00};
-			byte[] byteCount	= {0x00, 0x00};
+	/**
+	 * Builds the DCERPC packet
+	 * @return DCERPC packet
+	 */
+	private byte[] getDceRpc(byte[] transSub, int length) {
+		byte[] majorVersion	= {0x05};
+		byte[] minorVersion	= {0x00};
+		byte[] packetType	= null;
+		byte[] packetFlags	= {0x03};
+		byte[] dataRepres	= {0x10, 0x00, 0x00, 0x00};
+		byte[] fragLength	= null;
+		byte[] authLength	= {0x00, 0x00};
+		byte[] callID		= null;
+		byte[] response		= null;
 			
-			smbCommand			= new byte[]{0x04};
+		if(transSub[0] == 0x00 && transSub[1] == 0x0b) {
+			packetType	= new byte[]{0x0c};
+			fragLength	= new byte[]{0x44, 0x00};
+			callID		= new byte[]{0x01, 0x00, 0x00, 0x00};
+			byte[] maxXmitFrag		= {(byte) 0xb8, 0x10};
+			byte[] maxRecvFrag		= {(byte) 0xb8, 0x10};
+			byte[] assocGroup		= {0x4a, 0x41, 0x00, 0x00};
+			byte[] scndryAddrLen	= {0x0d, 0x00};
+			byte[] scndryAddr		= {0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c, 0x73, 0x72, 
+												0x76, 0x73, 0x76, 0x63, 0x00, 0x00};
+			byte[] numResults		= {0x01, 0x00, 0x00, 0x00};
+			byte[] ctxItem			= {0x00, 0x00, 0x00, 0x00, 0x04, 0x5d, (byte) 0x88, (byte) 0x8a,
+												(byte) 0xeb, 0x1c, (byte) 0xc9, 0x11, (byte) 0x9f, (byte) 0xe8,
+												0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00,	0x00, 0x00};
 			
-			byte[] response = HelperUtils.concat(wordCount, byteCount);
+			response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
+					authLength, callID, maxXmitFrag, maxRecvFrag, assocGroup, scndryAddrLen, scndryAddr, numResults, ctxItem);
+		} else if(transSub[0] == 0x00 && transSub[1] == 0x00) {
+			packetType	= new byte[]{0x02};
+			byte[] tmp	= ByteBuffer.allocate(4).putInt(length).array();
+			fragLength	= new byte[]{tmp[3], tmp[2]};
+			callID		= new byte[]{0x02, 0x00, 0x00, 0x00};
+			tmp			= ByteBuffer.allocate(4).putInt(length-24).array();
+			byte[] allocHint	= new byte[]{tmp[3], tmp[2], tmp[1], tmp[0]};
+			byte[] contextID	= {0x00, 0x00};
+			byte[] cancelCount	= {0x00, 0x00};
 			
-			return new Packet(wrapNetbios(wrapHeader(response)));
-		}
+			response = HelperUtils.concat(majorVersion, minorVersion, packetType, packetFlags, dataRepres,fragLength,
+					authLength, callID, allocHint, contextID, cancelCount);
+		}			
+		return response;
+	}
+	
+	/**
+	 * Builds the close packet
+	 * @return close packet
+	 */
+	private Packet getClose() {
+		byte[] wordCount	= {0x00};
+		byte[] byteCount	= {0x00, 0x00};
 		
-		/**
-		 * Builds the tree disconnect packet
-		 * @return tree disconnect packet
-		 */
-		private Packet getTreeDisc() {
-			byte[] wordCount	= {0x00};
-			byte[] byteCount	= {0x00, 0x00};
-			
-			smbCommand[0] = 0x71;
-			
-			byte[] response = HelperUtils.concat(wordCount, byteCount);
-			
-			return new Packet(wrapNetbios(wrapHeader(response)));
-		}
+		smbCommand			= new byte[]{0x04};
 		
-		/**
-		 * Builds the echo packet
-		 * @return echo packet
-		 */
-		private Packet getEcho() {
-			byte[] wordCount	= {0x01};
-			byte[] echoSeq		= {0x01, 0x00};
-			byte[] byteCount	= {0x10, 0x00};
-			byte[] echoData		= {(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
-									(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0}; 
-			byte[] response = HelperUtils.concat(wordCount, echoSeq, byteCount, echoData);
-			return new Packet(wrapNetbios(wrapHeader(response)));
-
-		}
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
 		
-		/**
-		 * Builds the trans2 packet
-		 * @return trans2 packet
-		 */
-		private Packet getTrans2() {
-			byte[] response = null;		
-			byte[] wordCount	= {0x00};
-			byte[] andXCommand	= {0x00, 0x00};
-			ntStat = new byte[] {0x22, 0x00, 0x00, (byte) 0xc0};
-			response = HelperUtils.concat(wordCount, andXCommand);
-			return new Packet(wrapNetbios(wrapHeader(response)));
-		}
+		return new Packet(wrapNetbios(wrapHeader(response)));
+	}
+	
+	/**
+	 * Builds the tree disconnect packet
+	 * @return tree disconnect packet
+	 */
+	private Packet getTreeDisc() {
+		byte[] wordCount	= {0x00};
+		byte[] byteCount	= {0x00, 0x00};
 		
-		/**
-		 * Extracts the trans sub packet from message
-		 * @return trans sub packet
-		 */		
-		private byte[] getTransSub() {
-			byte[] transSub = new byte[2];
-			if(smbCommand[0] == 0x32) transSub = new byte[]{message[66], message[65]};
-			else if(smbCommand[0] == 0x25) transSub = new byte[]{0x00, message[90]};
-			else transSub = new byte[]{0x00, 0x00};
-			return transSub;
-		}
-
-		public String toString() {
-			return HelperUtils.byteToStr(message);
-		}
+		smbCommand[0] = 0x71;
 		
-		/**
-		 * Returns the command number from the current message
-		 * @return command number
-		 */
-		private byte getSmbCommand() {
-			return smbCommand[0];
-		}
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
+		
+		return new Packet(wrapNetbios(wrapHeader(response)));
 	}
-}
+	
+	/**
+	 * Builds the echo packet
+	 * @return echo packet
+	 */
+	private Packet getEcho() {
+		byte[] wordCount	= {0x01};
+		byte[] echoSeq		= {0x01, 0x00};
+		byte[] byteCount	= {0x10, 0x00};
+		byte[] echoData		= {(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
+								(byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0}; 
+		byte[] response = HelperUtils.concat(wordCount, echoSeq, byteCount, echoData);
+		return new Packet(wrapNetbios(wrapHeader(response)));
+	}
+	
+	/**
+	 * Builds the trans2 packet
+	 * @return trans2 packet
+	 */
+	private Packet getTrans2() {
+		byte[] response = null;		
+		byte[] wordCount	= {0x00};
+		byte[] andXCommand	= {0x00, 0x00};
+		ntStat = new byte[] {0x22, 0x00, 0x00, (byte) 0xc0};
+		response = HelperUtils.concat(wordCount, andXCommand);
+		return new Packet(wrapNetbios(wrapHeader(response)));
+	}
+	
+	/**
+	 * Extracts the trans sub packet from message
+	 * @return trans sub packet
+	 */		
+	private byte[] getTransSub() {
+		byte[] transSub = new byte[2];
+		if(smbCommand[0] == 0x32) transSub = new byte[]{message[66], message[65]};
+		else if(smbCommand[0] == 0x25) transSub = new byte[]{0x00, message[90]};
+		else transSub = new byte[]{0x00, 0x00};
+		return transSub;
+	}
+	/**
+	 * Returns the command number from the current message
+	 * @return command number
+	 */
+	private byte getSmbCommand() {
+		return smbCommand[0];
+	}
+	
+	//message constants
+	private static final byte SMB_COM_CLOSE                  = 0x04;
+	private static final byte SMB_COM_TRANSACTION            = 0x25;
+	private static final byte SMB_COM_ECHO                   = 0x2B;
+	private static final byte SMB_COM_TRANSACTION2           = 0x32;
+	private static final byte SMB_COM_TREE_DISCONNECT        = 0x71;
+	private static final byte SMB_COM_NEGOTIATE              = 0x72;
+	private static final byte SMB_COM_SESSION_SETUP_ANDX     = 0x73;
+	private static final byte SMB_COM_TREE_CONNECT_ANDX      = 0x75;
+	private static final byte SMB_COM_NT_CREATE_ANDX         = (byte) 0xA2;
+	
+}

+ 275 - 232
src/de/tudarmstadt/informatik/hostage/protocol/SSH.java

@@ -23,6 +23,9 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
  * SSH protocol.
+ * Implementation of RFC documents 4250, 4251, 4252, 4253, 4254.
+ * It can handle the following requests: Server Protocol, Key Exchange Init, Diffie-Hellman Key Exchange Init, New Keys,
+ * Service Request, Connection Request, Channel Open Request, Channel Request.  
  * @author Wulf Pfeiffer
  */
 public class SSH implements Protocol {
@@ -30,25 +33,15 @@ public class SSH implements Protocol {
 	 * Represents the states of the protocol.
 	 */
 	private enum STATE {
-		NONE,
-		SERVER_VERSION,
-		CLIENT_VERSION,
-		KEX_INIT,
-		NEW_KEYS,
-		USERAUTH,
-		CONNECTION,
-		CHANNEL,
-		TERMINAL_CMD,
-		TERMINAL_ENTER,
-		CLOSED
+		NONE, SERVER_VERSION, CLIENT_VERSION, KEX_INIT, NEW_KEYS, USERAUTH, CONNECTION, CHANNEL, TERMINAL_CMD, TERMINAL_ENTER, CLOSED
 	}
-	
+
 	/**
 	 * Denotes in which state the protocol is right now.
 	 */
 	private STATE state = STATE.NONE;
 	private boolean useEncryption = false;
-		
+
 	@Override
 	public int getDefaultPort() {
 		return 22;
@@ -60,55 +53,55 @@ public class SSH implements Protocol {
 	}
 
 	@Override
-	public List<Packet> processMessage(Packet packet) {
-		List<Packet> response = new ArrayList<Packet>();
+	public List<Packet> processMessage(Packet requestPacket) {
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		byte[] request = null;
-		if(packet != null) {
-			request = packet.getMessage();
-			if(useEncryption) {
+		if (requestPacket != null) {
+			request = requestPacket.getMessage();
+			if (useEncryption) {
 				request = decryptBytes(request);
 			}
 		}
-		switch(state) {
-		case NONE:			
-			response.add(new Packet(serverVersion + serverType + "\r\n"));
+		switch (state) {
+		case NONE:
+			responsePackets.add(new Packet(serverVersion + serverType + "\r\n"));
 			state = STATE.SERVER_VERSION;
 			break;
 		case SERVER_VERSION:
 			extractType(request);
 			extractPayload(request);
-			response.add(kexInit());
+			responsePackets.add(kexInit());
 			state = STATE.CLIENT_VERSION;
 			break;
 		case CLIENT_VERSION:
 			extractPubKey(request);
-			response.add(dhKexReply());
+			responsePackets.add(dhKexReply());
 			state = STATE.KEX_INIT;
 			break;
 		case KEX_INIT:
-			response.add(newKeys());
+			responsePackets.add(newKeys());
 			useEncryption = true;
 			state = STATE.NEW_KEYS;
 			break;
 		case NEW_KEYS:
-			response.add(serviceReply(request));
+			responsePackets.add(serviceReply(request));
 			state = STATE.USERAUTH;
 			break;
 		case USERAUTH:
-			response.add(connectionReply(request));
+			responsePackets.add(connectionReply(request));
 			state = STATE.CONNECTION;
 			break;
 		case CONNECTION:
-			response.add(channelOpenReply(request));
+			responsePackets.add(channelOpenReply(request));
 			state = STATE.CHANNEL;
 			break;
 		case CHANNEL:
-			response.add(channelSuccessReply(request));
-			response.add(terminalPrefix());
+			responsePackets.add(channelSuccessReply(request));
+			responsePackets.add(terminalPrefix());
 			state = STATE.TERMINAL_CMD;
 			break;
 		case TERMINAL_CMD:
-			response.add(terminalReply(request));
+			responsePackets.add(terminalReply(request));
 			break;
 		case CLOSED:
 			break;
@@ -116,8 +109,8 @@ public class SSH implements Protocol {
 			state = STATE.CLOSED;
 			break;
 		}
-		
-		return response;
+
+		return responsePackets;
 	}
 
 	@Override
@@ -142,175 +135,200 @@ public class SSH implements Protocol {
 
 	/**
 	 * Wraps the packets with packet length and padding.
-	 * @param packet content that is wrapped.
+	 * 
+	 * @param response
+	 *            content that is wrapped.
 	 * @return wrapped packet.
 	 */
-	private Packet wrapPacket(byte[] packet) {
-		int packetLength = 5 + packet.length; 	//4 byte packet length, 1 byte padding length, payload length
-		int paddingLengthCBS = cipherBlockSize - (packetLength % cipherBlockSize);
+	private Packet wrapPacket(byte[] response) {
+		int packetLength = 5 + response.length; // 4 byte packet length, 1 byte padding length, payload length
+		int paddingLengthCBS = cipherBlockSize
+				- (packetLength % cipherBlockSize);
 		int paddingLength8 = 8 - (packetLength % 8);
-		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS : paddingLength8;
-		if(paddingLength < 4) paddingLength += cipherBlockSize;
-		packetLength = packetLength + paddingLength - 4;					//add padding string length to packet length
-		
+		int paddingLength = paddingLengthCBS > paddingLength8 ? paddingLengthCBS
+				: paddingLength8;
+		if (paddingLength < 4)
+			paddingLength += cipherBlockSize;
+		packetLength = packetLength + paddingLength - 4; // add padding string length to packet length
+
 		byte[] packetLen = ByteBuffer.allocate(4).putInt(packetLength).array();
-		byte[] paddingLen = {(byte) paddingLength};
+		byte[] paddingLen = { (byte) paddingLength };
 		byte[] paddingString = HelperUtils.randomBytes(paddingLength);
-		byte[] response = HelperUtils.concat(packetLen, paddingLen, packet, paddingString);
-		if(useEncryption) {
-			byte[] mac = getMac(response);
-			byte[] responseEnc = encryptBytes(response);
-			response = HelperUtils.concat(responseEnc,mac);
+		byte[] wrappedResponse = HelperUtils.concat(packetLen, paddingLen, response,
+				paddingString);
+		if (useEncryption) {
+			byte[] mac = createMac(wrappedResponse);
+			byte[] responseEnc = encryptBytes(wrappedResponse);
+			wrappedResponse = HelperUtils.concat(responseEnc, mac);
 		}
 		packetNumber++;
-		
-		return new Packet(response);
+
+		return new Packet(wrappedResponse);
 	}
-	
+
 	/**
 	 * Encrypts a request with triple DES.
-	 * @param request that is encrypted.
+	 * 
+	 * @param request
+	 *            that is encrypted.
 	 * @return encrypted request.
 	 */
 	private byte[] encryptBytes(byte[] bytes) {
-		byte[] responseEnc = new byte[bytes.length];
-		for(int i = 0; i < bytes.length; i+=8) { 
-			cbcEnc.transformBlock(bytes, i, responseEnc, i);
+		byte[] responseEncrypted = new byte[bytes.length];
+		for (int i = 0; i < bytes.length; i += 8) {
+			cbcEncryption.transformBlock(bytes, i, responseEncrypted, i);
 		}
-		return responseEnc;
+		return responseEncrypted;
 	}
-	
+
 	/**
 	 * Decrypts a request with triple DES.
-	 * @param request that is decrypted.
+	 * 
+	 * @param request
+	 *            that is decrypted.
 	 * @return decrypted request.
 	 */
 	private byte[] decryptBytes(byte[] request) {
-		byte[] message = new byte[request.length - ((request.length % 8 == 0) ? 0 : 20)];
-		for(int i = 0; i < message.length; i += 8) { // -12 wegen MAC
-			cbcDec.transformBlock(request, i, message, i);
+		byte[] decryptedRequest = new byte[request.length
+				- ((request.length % 8 == 0) ? 0 : 20)];
+		for (int i = 0; i < decryptedRequest.length; i += 8) { // -12 wegen MAC
+			cbcDecryption.transformBlock(request, i, decryptedRequest, i);
 		}
-		return message;
+		return decryptedRequest;
 	}
-	
+
 	/**
 	 * Creates the SHA1 Mac with the given bytes.
-	 * @param bytes that are used for the Mac.
+	 * 
+	 * @param bytes
+	 *            that are used for the Mac.
 	 * @return Mac.
 	 */
-	private byte[] getMac(byte[] bytes) {
+	private byte[] createMac(byte[] bytes) {
 		byte[] mac = new byte[20];
-		macEnc.initMac(packetNumber);
-		macEnc.update(bytes, 0, bytes.length);
-		macEnc.getMac(mac, 0);
+		macEncryption.initMac(packetNumber);
+		macEncryption.update(bytes, 0, bytes.length);
+		macEncryption.getMac(mac, 0);
 		return mac;
 	}
-	
+
 	/**
-	 * Builds the Kex Init packet that contains all the allowed algorithms by the server.
+	 * Builds the Kex Init packet that contains all the allowed algorithms by
+	 * the server.
+	 * 
 	 * @return Kex Init packet.
 	 */
 	private Packet kexInit() {
 		TypesWriter tw = new TypesWriter();
 		tw.writeByte(0x14);
-		tw.writeBytes(HelperUtils.randomBytes(16)); //cookie
-		tw.writeString(kex_alg);
-		tw.writeString(server_alg);
-		tw.writeString(encrypt_alg_c);
-		tw.writeString(encrypt_alg_s);
-		tw.writeString(mac_alg_c);
-		tw.writeString(mac_alg_s);
-		tw.writeString(comp_alg_c);
-		tw.writeString(comp_alg_s);
-		tw.writeBytes(new byte[]{0x00, 0x00, 0x00, 0x00}); //language client to server
-		tw.writeBytes(new byte[]{0x00, 0x00, 0x00, 0x00}); //language server to client
-		tw.writeByte(0x00); //no guess from server
-		tw.writeBytes(new byte[]{0x00, 0x00, 0x00, 0x00}); //reserved
+		tw.writeBytes(HelperUtils.randomBytes(16)); // cookie
+		tw.writeString(KEX_ALG);
+		tw.writeString(SERVER_ALG);
+		tw.writeString(ENCRYPT_ALG_C);
+		tw.writeString(ENCRYPT_ALG_S);
+		tw.writeString(MAC_ALG_C);
+		tw.writeString(MAC_ALG_S);
+		tw.writeString(COMP_ALG_C);
+		tw.writeString(COMP_ALG_S);
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language client to server
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // language server to client
+		tw.writeByte(0x00); // no guess from server
+		tw.writeBytes(new byte[] { 0x00, 0x00, 0x00, 0x00 }); // reserved
 		byte[] response = tw.getBytes();
 		I_S = response;
-		
+
 		return wrapPacket(response);
 	}
-	
+
 	/**
-	 * Builds the Diffie-Hellman Kex Reply, containing the host key,f and the signature.
+	 * Builds the Diffie-Hellman Kex Reply, containing the host key,f and the
+	 * signature.
+	 * 
 	 * @return Diffie-Hellman Kex Reply packet.
 	 */
 	private Packet dhKexReply() {
 		byte[] response = null;
 		try {
 			DhExchange dhx = new DhExchange();
-			dhx.serverInit(1, rndm);
+			dhx.serverInit(1, random);
 			dhx.setE(new BigInteger(e));
 			f = dhx.getF();
-			DSAPrivateKey dsa = (DSAPrivateKey) PEMDecoder.decode(dsa_pem, null);
+			DSAPrivateKey dsa = (DSAPrivateKey) PEMDecoder
+					.decode(dsaPem, null);
 			K_S = DSASHA1Verify.encodeSSHDSAPublicKey(dsa.getPublicKey());
 			h = dhx.calculateH(V_C, V_S, I_C, I_S, K_S);
 			k = dhx.getK();
-			DSASignature ds = DSASHA1Verify.generateSignature(h, dsa, rndm);
-			sig = DSASHA1Verify.encodeSSHDSASignature(ds);
+			DSASignature ds = DSASHA1Verify.generateSignature(h, dsa, random);
+			signature = DSASHA1Verify.encodeSSHDSASignature(ds);
 			TypesWriter tw = new TypesWriter();
 			tw.writeByte(31);
 			tw.writeString(K_S, 0, K_S.length);
 			tw.writeMPInt(f);
-			tw.writeString(sig, 0, sig.length);
+			tw.writeString(signature, 0, signature.length);
 			response = tw.getBytes();
 			
-			//init for decryption and encryption
-			KeyMaterial km = KeyMaterial.create("SHA1", h, k, h, 24, 8, 20, 24, 8, 20); // alg, h, k, keylength, blocklength, maclength, keylength, blocklength, maclength
-			enc = new DESede();
-			dec = new DESede();
-			enc.init(true, km.enc_key_server_to_client);
-			dec.init(false, km.enc_key_client_to_server);
-			cbcEnc = new CBCMode(enc, km.initial_iv_server_to_client, true);
-			cbcDec = new CBCMode(dec, km.initial_iv_client_to_server, false);
-			macEnc = new MAC("hmac-sha1", km.integrity_key_server_to_client);
-//			macDec = new MAC("hmac-sha1", km.integrity_key_client_to_server);
+			// init for decryption and encryption
+			KeyMaterial km = KeyMaterial.create("SHA1", h, k, h, 24, 8, 20, 24,
+					8, 20); // alg, h, k, keylength, blocklength, maclength, keylength, blocklength, maclength
+			desEncryption = new DESede();
+			desDecryption = new DESede();
+			desEncryption.init(true, km.enc_key_server_to_client);
+			desDecryption.init(false, km.enc_key_client_to_server);
+			cbcEncryption = new CBCMode(desEncryption, km.initial_iv_server_to_client, true);
+			cbcDecryption = new CBCMode(desDecryption, km.initial_iv_client_to_server, false);
+			macEncryption = new MAC("hmac-sha1", km.integrity_key_server_to_client);
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
-		
+
 		return wrapPacket(response);
 	}
 
 	/**
 	 * New Keys response.
+	 * 
 	 * @return New Keys response.
 	 */
 	private Packet newKeys() {
-		byte[] msgCode = {0x15};
+		byte[] msgCode = { 0x15 };
 		return wrapPacket(msgCode);
 	}
-	
+
 	/**
 	 * Service ssh-userauth reply.
-	 * @param request from the client.
+	 * 
+	 * @param request
+	 *            from the client.
 	 * @return Service reply.
 	 */
 	private Packet serviceReply(byte[] request) {
 		byte[] message;
-		if(request[5] == 0x15) {	//if newkeys request is included in the same packet
-			message = new byte[request.length - 16]; //remove it
-			System.arraycopy(request, 16, message, 0, request.length-16);
+		if (request[5] == 0x15) { // if newkeys request is included in the same packet
+			message = new byte[request.length - 16]; // remove it
+			System.arraycopy(request, 16, message, 0, request.length - 16);
 		} else {
 			message = request;
 		}
-		if (message[5] != 0x05 && !(HelperUtils.byteToStr(message).contains("ssh-userauth"))) {
+		if (message[5] != 0x05
+				&& !(HelperUtils.byteToStr(message).contains("ssh-userauth"))) {
 			return disconnectReply(7); // disconnect because its not servicerequest ssh-userauth
 		}
 		TypesWriter tw = new TypesWriter();
 		tw.writeByte(0x06);
 		tw.writeString("ssh-userauth");
-		return wrapPacket(tw.getBytes());		
+		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
 	 * Userauth ssh-connection reply.
-	 * @param request from the client.
+	 * 
+	 * @param request
+	 *            from the client.
 	 * @return ssh-connection reply.
 	 */
 	private Packet connectionReply(byte[] request) {
-		if (request[5] != 0x32 && !(HelperUtils.byteToStr(request).contains("ssh-connection"))) {
+		if (request[5] != 0x32
+				&& !(HelperUtils.byteToStr(request).contains("ssh-connection"))) {
 			return disconnectReply(14);// disconnect because its not servicerequest ssh-connect
 		}
 		try {
@@ -320,13 +338,15 @@ public class SSH implements Protocol {
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
-		byte[] msgcode = {0x34};		
-		return wrapPacket(msgcode);		
+		byte[] msgcode = { 0x34 };
+		return wrapPacket(msgcode);
 	}
-	
+
 	/**
 	 * Channel Open Reply.
-	 * @param request from client.
+	 * 
+	 * @param request
+	 *            from client.
 	 * @return Channel Open Reply.
 	 */
 	private Packet channelOpenReply(byte[] request) {
@@ -341,8 +361,8 @@ public class SSH implements Protocol {
 			int senderChannel = recipientChannel;
 			int initialWindowSize = tr.readUINT32();
 			int maximumPacketSize = tr.readUINT32();
-			
-			tw.writeByte(0x5b); //msgcode
+
+			tw.writeByte(0x5b); // msgcode
 			tw.writeUINT32(recipientChannel);
 			tw.writeUINT32(senderChannel);
 			tw.writeUINT32(initialWindowSize);
@@ -350,28 +370,31 @@ public class SSH implements Protocol {
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
-		
+
 		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
 	 * Channel Success Reply.
-	 * @param request from client.
+	 * 
+	 * @param request
+	 *            from client.
 	 * @return Channel Success Reply.
 	 */
 	private Packet channelSuccessReply(byte[] request) {
-		if(!(HelperUtils.byteToStr(request)).contains("pty-req")) {
+		if (!(HelperUtils.byteToStr(request)).contains("pty-req")) {
 			return disconnectReply(2);
 		}
 		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x63); //msgcode
+		tw.writeByte(0x63); // msgcode
 		tw.writeUINT32(recipientChannel);
-		
+
 		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
 	 * Returns the terminal prefix for the client.
+	 * 
 	 * @return terminal prefix.
 	 */
 	private Packet terminalPrefix() {
@@ -379,201 +402,221 @@ public class SSH implements Protocol {
 		tw.writeByte(0x5e);
 		tw.writeUINT32(recipientChannel);
 		tw.writeString(terminalPrefix);
+		
 		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
 	 * Computes the reply for the client input.
-	 * @param request client input.
+	 * 
+	 * @param request
+	 *            client input.
 	 * @return input reply.
 	 */
 	private Packet terminalReply(byte[] request) {
 		TypesReader tr = new TypesReader(request, 6);
-		String msg = "";
+		String messsage = "";
 		System.out.println(HelperUtils.bytesToHexString(request));
 		try {
 			tr.readUINT32();
-			msg = tr.readString();
-			System.out.println(msg);
-			if(msg.contains("\r")) {
+			messsage = tr.readString();
+			System.out.println(messsage);
+			if (messsage.contains("\r")) {
 				System.out.println("hi");
-				if(cmd.toString().contains("exit")) {
+				if (command.toString().contains("exit")) {
 					state = STATE.CLOSED; // ugly style
 					return disconnectReply(2);
 				}
-				msg = "\r\nbash: " + cmd + " :command not found\r\n"	+ terminalPrefix;
-				cmd = new StringBuffer();
-			} else if(msg.contains(new String(new char[]{'\u007F'})) && cmd.length() > 0) {
-				cmd = cmd.delete(cmd.length()-1, cmd.length());
+				messsage = "\r\nbash: " + command + " :command not found\r\n"
+						+ terminalPrefix;
+				command = new StringBuffer();
+			} else if (messsage.contains(new String(new char[] { '\u007F' }))
+					&& command.length() > 0) {
+				command = command.delete(command.length() - 1, command.length());
 			} else {
-				cmd.append(msg);
+				command.append(messsage);
 			}
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
 		TypesWriter tw = new TypesWriter();
-		tw.writeByte(0x5e); //msgcode
+		tw.writeByte(0x5e); // msgcode
 		tw.writeUINT32(recipientChannel);
-		tw.writeString(msg);
+		tw.writeString(messsage);
 		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
 	 * Disconnect Reply using the given number as reason code.
-	 * @param reasonCode for disconnect reply. Must be between 1 and 15, default is 2.
+	 * 
+	 * @param reasonCode
+	 *            for disconnect reply. Must be between 1 and 15, default is 2.
 	 * @return Disconnect Reply.
 	 */
 	private Packet disconnectReply(int reasonCode) {
 		TypesWriter tw = new TypesWriter();
 		tw.writeByte(0x01);
 		switch (reasonCode) {
-		case 1: 
+		case 1:
 			tw.writeUINT32(1);
 			tw.writeString("SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT");
 			break;
-		case 7: 
+		case 7:
 			tw.writeUINT32(7);
 			tw.writeString("SSH_DISCONNECT_SERVICE_NOT_AVAILABLE");
 			break;
-		case 14: 
+		case 14:
 			tw.writeUINT32(14);
 			tw.writeString("SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE");
 			break;
-		default: 
+		default:
 			tw.writeUINT32(2);
 			tw.writeString("SSH_DISCONNECT_PROTOCOL_ERROR");
 			break;
 		}
 		return wrapPacket(tw.getBytes());
 	}
-	
+
 	/**
 	 * Extracts the type of the client
-	 * @param request containing the clients type
+	 * 
+	 * @param request
+	 *            containing the clients type
 	 */
 	private void extractType(byte[] request) {
 		int length = 0;
-		for(int i = 0; i < request.length; i++, length++) { 	
-			if(request[i] == 0x0d) break;			//find the end of the type: '\r'
+		for (int i = 0; i < request.length; i++, length++) {
+			if (request[i] == 0x0d)
+				break; // find the end of the type: '\r'
 		}
 		V_C = new byte[length];
 		System.arraycopy(request, 0, V_C, 0, length);
 	}
-	
+
 	/**
 	 * Extracts the payload of a packet and writes it in I_C.
-	 * @param request packet of which the payload is extracted.
+	 * 
+	 * @param request
+	 *            packet of which the payload is extracted.
 	 */
 	private void extractPayload(byte[] request) {
-		int pos = 0;
-		if(request[5] != 0x14) {
-			pos = 1;
-			for(int i = 0; i < request.length; i++, pos++) {
-				if(request[i] == 0xa) break;
+		int position = 0;
+		if (request[5] != 0x14) {
+			position = 1;
+			for (int i = 0; i < request.length; i++, position++) {
+				if (request[i] == 0xa)
+					break;
 			}
 		}
-		int packetLength = byteToInt(new byte[]{request[pos], request[1+pos], request[2+pos], request[3+pos]});
-		int paddingLength = byteToInt(new byte[]{request[4+pos]});
+		int packetLength = byteToInt(new byte[] { request[position], request[1 + position], request[2 + position], request[3 + position] });
+		int paddingLength = byteToInt(new byte[] { request[4 + position] });
 		byte[] payload = new byte[packetLength - paddingLength - 1];
-		for(int i = 5; i < packetLength - paddingLength - 1; i++) {
-			payload[i-5] = request[i+pos];
+		for (int i = 5; i < packetLength - paddingLength - 1; i++) {
+			payload[i - 5] = request[i + position];
 		}
 		I_C = payload;
 	}
-	
+
 	/**
 	 * Extracts the public key from the DH Kex Request
-	 * @param request containing the clients public key
+	 * 
+	 * @param request
+	 *            containing the clients public key
 	 */
 	private void extractPubKey(byte[] request) {
-		e = new byte[byteToInt(new byte[] {request[6], request[7], request[8], request[9]})];
-		for(int i = 0; i < e.length; i++) {
-			e[i] = request[i+10];
+		e = new byte[byteToInt(new byte[] { request[6], request[7], request[8],
+				request[9] })];
+		for (int i = 0; i < e.length; i++) {
+			e[i] = request[i + 10];
 		}
 	}
-	
+
 	/**
 	 * Converts a byte[] to int
-	 * @param bytes that are converted
+	 * 
+	 * @param bytes
+	 *            that are converted
 	 * @return converted byte[] as int
 	 */
 	private static int byteToInt(byte[] bytes) {
-		  int ret = 0;
-		  for (int i=0; i < bytes.length; i++) {
-		    ret <<= 8;
-		    ret |= bytes[i] & 0xFF;
-		  }
-		  return ret;
+		int convertedInteger = 0;
+		for (int i = 0; i < bytes.length; i++) {
+			convertedInteger <<= 8;
+			convertedInteger |= bytes[i] & 0xFF;
+		}
+		return convertedInteger;
 	}
-	
-	//version stuff
+
+	// version stuff
 	private static String[][][] possibleSshTypes = {
-		{{"3."},{"4","5","6","7","8","9"}},
-		{{"4."},{"0","1","2","3","4","5","6","7","9"}},
-		{{"5."},{"0","1","2","3","4","5","6","7","8","9"}},
-		{{"6."},{"0","1","2","3","4"}}
-	};
+			{ { "3." }, { "4", "5", "6", "7", "8", "9" } },
+			{ { "4." }, { "0", "1", "2", "3", "4", "5", "6", "7", "9" } },
+			{ { "5." }, { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" } },
+			{ { "6." }, { "0", "1", "2", "3", "4" } } };
 
 	private static String initSshType() {
 		SecureRandom rnd = new SecureRandom();
 		int majorVersion = rnd.nextInt(possibleSshTypes.length);
-		return "OpenSSH_" + possibleSshTypes[majorVersion][0][0] + possibleSshTypes[majorVersion][1][rnd.nextInt(possibleSshTypes[majorVersion][1].length)];
+		return "OpenSSH_"
+				+ possibleSshTypes[majorVersion][0][0]
+				+ possibleSshTypes[majorVersion][1][rnd
+						.nextInt(possibleSshTypes[majorVersion][1].length)];
 	}
 
-	//server infos
-	private static String serverVersion	= "SSH-2.0-";
-	private static String serverType	= initSshType();
-	private static String serverName	= HelperUtils.getRandomString(16, false);
-	private int packetNumber			= 0;
+	// server infos
+	private static String serverVersion = "SSH-2.0-";
+	private static String serverType = initSshType();
+	private static String serverName = HelperUtils.getRandomString(16, false);
+	private int packetNumber = 0;
 	private int recipientChannel;
 	private String userName;
 	private String terminalPrefix;
-	private StringBuffer cmd			= new StringBuffer();
-	private SecureRandom rndm	= new SecureRandom();
-	
-	//SSH Parameters for Kex etc.
-    private byte[] V_S = (serverVersion + serverType).getBytes();
-    private byte[] V_C;
-    private byte[] I_S;
-    private byte[] I_C;
-    private byte[] e;
-    private BigInteger f;
-    private byte[] h;
-    private BigInteger k;
-    private byte[] K_S;
-    private byte[] sig;
-			
-    //allowed algorithms for kexinit
-	private String kex_alg = "diffie-hellman-group1-sha1";
-	private String server_alg = "ssh-dss";
-	private String encrypt_alg_c = "3des-cbc";
-	private String encrypt_alg_s = "3des-cbc";
-	private String mac_alg_c = "hmac-sha1";
-	private String mac_alg_s = "hmac-sha1";
-	private String comp_alg_c = "none";
-	private String comp_alg_s = "none";
-	
+	private StringBuffer command = new StringBuffer();
+	private SecureRandom random = new SecureRandom();
+
+	// SSH Parameters for Kex etc.
+	private byte[] V_S = (serverVersion + serverType).getBytes();
+	private byte[] V_C;
+	private byte[] I_S;
+	private byte[] I_C;
+	private byte[] e;
+	private BigInteger f;
+	private byte[] h;
+	private BigInteger k;
+	private byte[] K_S;
+	private byte[] signature;
+
+	// allowed algorithms for kexinit
+	private static final String KEX_ALG			= "diffie-hellman-group1-sha1";
+	private static final String SERVER_ALG		= "ssh-dss";
+	private static final String ENCRYPT_ALG_C	= "3des-cbc";
+	private static final String ENCRYPT_ALG_S	= "3des-cbc";
+	private static final String MAC_ALG_C		= "hmac-sha1";
+	private static final String MAC_ALG_S		= "hmac-sha1";
+	private static final String COMP_ALG_C		= "none";
+	private static final String COMP_ALG_S		= "none";
+
 	private int cipherBlockSize = 16;
-	
-	//for en- and decryption
-	private DESede enc;
-	private DESede dec;
-	private CBCMode cbcEnc;
-	private CBCMode cbcDec;
-	private MAC macEnc;
-//	private MAC macDec;
-	
-	//dsa private key
-	private final char[] dsa_pem = ("-----BEGIN DSA PRIVATE KEY-----\n" +
-			"MIIBugIBAAKBgQCDZ9R2vfCPwjv5vKF1igIv9drrZ7G0dhMkGT9AZTjgI34Qm4w0\n" +
-			"0iWeCqO7SmqiaMIjbRIm91MeDed4ObAq4sAkqRE/2P4mTbzFx5KhEczRRiDoqQBX\n" +
-			"xYa0yWKJpeZ94SGM6DEPuBTxKo0T4uMjbq2FzHL2FXT1/WoNCmRU6gFSiwIVAMK4\n" +
-			"Epz3JiwDUbkSpLOjIqtEhJmVAoGAL6zlXRI4Q8iwvSDh0vDf1j9a5Aaaq+93LTjK\n" +
-			"SwL4nvUWBl2Aa0vqu05ZS5rOD1I+/naLMg0fNgFJRhA03sl+12MI3a2HXJWXRSdj\n" +
-			"m1Vq9cUXqiYrX6+iGfEaA/y9UO4ZPF6if6eLypXB8VuqjtjDCiMMsM6+qQki7L71\n" +
-			"yN4M75ICgYAcFXUhN2zRug3JvwmGxW8gMgHquSiBnbx1582KGh2B/ukE/kOrbKYD\n" +
-			"HUkBzolcm4x1Odq5apowlriFxY6zMQP615plIK4x9NaU6dvc/HoTkjzT5EYSMN39\n" +
-			"eAGufJ0jrtIpKL4lP8o8yrAHfmbR7bjecWc0viTH0+OWlyVsex/bZAIUEKn310Li\n" +
-			"v62Zs4hlDvhwvx8MQ+A=\n" +
-			"-----END DSA PRIVATE KEY-----").toCharArray();
+
+	// for en- and decryption
+	private DESede desEncryption;
+	private DESede desDecryption;
+	private CBCMode cbcEncryption;
+	private CBCMode cbcDecryption;
+	private MAC macEncryption;
+	// private MAC macDec;
+
+	// dsa private key
+	private final char[] dsaPem = ("-----BEGIN DSA PRIVATE KEY-----\n"
+			+ "MIIBugIBAAKBgQCDZ9R2vfCPwjv5vKF1igIv9drrZ7G0dhMkGT9AZTjgI34Qm4w0\n"
+			+ "0iWeCqO7SmqiaMIjbRIm91MeDed4ObAq4sAkqRE/2P4mTbzFx5KhEczRRiDoqQBX\n"
+			+ "xYa0yWKJpeZ94SGM6DEPuBTxKo0T4uMjbq2FzHL2FXT1/WoNCmRU6gFSiwIVAMK4\n"
+			+ "Epz3JiwDUbkSpLOjIqtEhJmVAoGAL6zlXRI4Q8iwvSDh0vDf1j9a5Aaaq+93LTjK\n"
+			+ "SwL4nvUWBl2Aa0vqu05ZS5rOD1I+/naLMg0fNgFJRhA03sl+12MI3a2HXJWXRSdj\n"
+			+ "m1Vq9cUXqiYrX6+iGfEaA/y9UO4ZPF6if6eLypXB8VuqjtjDCiMMsM6+qQki7L71\n"
+			+ "yN4M75ICgYAcFXUhN2zRug3JvwmGxW8gMgHquSiBnbx1582KGh2B/ukE/kOrbKYD\n"
+			+ "HUkBzolcm4x1Odq5apowlriFxY6zMQP615plIK4x9NaU6dvc/HoTkjzT5EYSMN39\n"
+			+ "eAGufJ0jrtIpKL4lP8o8yrAHfmbR7bjecWc0viTH0+OWlyVsex/bZAIUEKn310Li\n"
+			+ "v62Zs4hlDvhwvx8MQ+A=\n" + "-----END DSA PRIVATE KEY-----")
+			.toCharArray();
 }

+ 39 - 38
src/de/tudarmstadt/informatik/hostage/protocol/TELNET.java

@@ -7,7 +7,8 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
- * TELNET protocol
+ * TELNET protocol.
+ * Implementation of RFC document 854.
  * @author Wulf Pfeiffer
  */
 public class TELNET implements Protocol {
@@ -34,22 +35,22 @@ public class TELNET implements Protocol {
 	}
 
 	@Override
-	public List<Packet> processMessage(Packet packet) {
+	public List<Packet> processMessage(Packet requestPacket) {
 		byte[] request = null;
-		if(packet != null) {
-			request = packet.getMessage();
+		if(requestPacket != null) {
+			request = requestPacket.getMessage();
 		}
-		List<Packet> response = new ArrayList<Packet>();
+		List<Packet> responsePackets = new ArrayList<Packet>();
 		
 		switch (state) {
 		case NONE:
-			response.add(new Packet(optionRequest));
+			responsePackets.add(new Packet(optionRequest));
 			state = STATE.OPEN;
 			break;
 		case OPEN:
 			if(request != null) {
-				response.add(new Packet(getOptionResponse(request)));
-				response.add(new Packet(serverName + " login: "));
+				responsePackets.add(new Packet(getOptionResponse(request)));
+				responsePackets.add(new Packet(serverName + " login: "));
 				state = STATE.LOGIN;
 			}
 			break;
@@ -60,10 +61,10 @@ public class TELNET implements Protocol {
 					byte[] buffer = new byte[request.length - 2]; 
 					System.arraycopy(request, 0, buffer, 0, request.length - 2); 
 					user = HelperUtils.concat(user, buffer);
-					response.add(new Packet(buffer));
+					responsePackets.add(new Packet(buffer));
 				}
-				response.add(new Packet("\r\n"));
-				response.add(new Packet("Password: "));
+				responsePackets.add(new Packet("\r\n"));
+				responsePackets.add(new Packet("Password: "));
 				state = STATE.AUTHENTICATE;
 				sessionToken = HelperUtils.concat(sessionPrefix, user, "@".getBytes(), serverName.getBytes(), sessionMiddle, user, "@".getBytes(), serverName.getBytes(), sessionSuffix);
 				break;
@@ -71,24 +72,24 @@ public class TELNET implements Protocol {
 				byte[] tmp = new byte[user.length - 1];
 				System.arraycopy(user, 0, tmp, 0, user.length - 1);
 				user = tmp;
-				response.add(new Packet("\b \b"));
+				responsePackets.add(new Packet("\b \b"));
 				break;
 			} else if (!checkForByte(request, (byte) 0xff)){
 				if(user == null)
 					user = request;
 				else
 					user = HelperUtils.concat(user, request);
-				response.add(packet);
+				responsePackets.add(requestPacket);
 			}
 			break;
 		case AUTHENTICATE:
 			if(request == null) break;
 			else if(checkForByte(request, (byte) 0x0d)) {
-				response.add(new Packet("\r\n"));
-				response.add(new Packet(sessionToken));
+				responsePackets.add(new Packet("\r\n"));
+				responsePackets.add(new Packet(sessionToken));
 				state = STATE.LOGGED_IN;
 			} else if (checkForByte(request, (byte) 0x7f)) {
-				response.add(new Packet("\b \b"));
+				responsePackets.add(new Packet("\b \b"));
 			}			
 			break;
 		case LOGGED_IN:
@@ -98,41 +99,41 @@ public class TELNET implements Protocol {
 					byte[] buffer = new byte[request.length - 2]; 
 					System.arraycopy(request, 0, buffer, 0, request.length - 2); 
 					command = HelperUtils.concat(command, buffer);
-					response.add(new Packet(buffer));
+					responsePackets.add(new Packet(buffer));
 				}
 				if(command == null) {
-					response.add(new Packet("\r\n"));
-					response.add(new Packet(sessionToken));
+					responsePackets.add(new Packet("\r\n"));
+					responsePackets.add(new Packet(sessionToken));
 				} else if (new String(command).contains("exit")) {
-					response.add(new Packet("\r\nlogout\r\n"));
+					responsePackets.add(new Packet("\r\nlogout\r\n"));
 					state = STATE.CLOSED;
 				} else {
 					String bash = "\r\n-bash: " + new String(command)+ ": command not found";
-					response.add(new Packet(bash));
-					response.add(new Packet("\r\n"));
-					response.add(new Packet(sessionToken));
+					responsePackets.add(new Packet(bash));
+					responsePackets.add(new Packet("\r\n"));
+					responsePackets.add(new Packet(sessionToken));
 					command = null;
 				}
 			} else if (checkForByte(request, (byte) 0x7f) && command != null && command.length != 0) {
 				byte[] tmp = new byte[command.length - 1];
 				System.arraycopy(command, 0, tmp, 0, command.length - 1);
 				command = tmp;
-				response.add(new Packet("\b \b"));
+				responsePackets.add(new Packet("\b \b"));
 				break;
 			} else if (!checkForByte(request, (byte) 0xff)){
 				if(command == null)
 					command = request;
 				else
 					command = HelperUtils.concat(command, request);
-				response.add(packet);
+				responsePackets.add(requestPacket);
 			}
 			break;
 		default:
-			response.add(new Packet("\r\nlogout\r\n"));
+			responsePackets.add(new Packet("\r\nlogout\r\n"));
 			state = STATE.CLOSED;
 			break;
 		}
-		return response;
+		return responsePackets;
 	}
 
 	@Override
@@ -174,22 +175,22 @@ public class TELNET implements Protocol {
 	 * @return accepted and unaccepted options
 	 */
 	private byte[] getOptionResponse(byte[] request) {
-		List<byte[]> respList = new ArrayList<byte[]>();
-		byte[] cmdResp;
+		List<byte[]> responseList = new ArrayList<byte[]>();
+		byte[] requestInverse;
 		for(int i = 0; i < request.length - 2; i += 3) {
 			if(request[i] == (byte) 0xff && request[i+2] != 0x03 && request[i+2] != 0x01) {
-				cmdResp = new byte[3];
-				cmdResp[0] = request[i];
-				cmdResp[1] = request[i+1] == (byte) 0xfd ? (byte) 0xfc : (byte) 0xfe; 
-				cmdResp[2] = request[i+2];
-				respList.add(cmdResp);
+				requestInverse = new byte[3];
+				requestInverse[0] = request[i];
+				requestInverse[1] = request[i+1] == (byte) 0xfd ? (byte) 0xfc : (byte) 0xfe; 
+				requestInverse[2] = request[i+2];
+				responseList.add(requestInverse);
 			}			
 		}
-		byte[] response = new byte[0];
-		for(byte[] resp : respList) {
-			response = HelperUtils.concat(response, resp);
+		byte[] optionResponse = new byte[0];
+		for(byte[] response : responseList) {
+			optionResponse = HelperUtils.concat(optionResponse, response);
 		}
-		return response;
+		return optionResponse;
 	}