Browse Source

-SMB: Restructured
-added NBNS for registrating SMB in the network (right now only for
existing workgroups
-changed Packet to fix log view bug

Wulf Pfeiffer 10 years ago
parent
commit
7573f322d7

+ 4 - 0
src/de/tudarmstadt/informatik/hostage/Listener.java

@@ -11,6 +11,7 @@ import javax.net.ssl.SSLSocketFactory;
 
 import de.tudarmstadt.informatik.hostage.net.MyServerSocketFactory;
 import de.tudarmstadt.informatik.hostage.protocol.Protocol;
+import de.tudarmstadt.informatik.hostage.protocol.SMB;
 import de.tudarmstadt.informatik.hostage.protocol.SSLProtocol;
 
 /**
@@ -126,6 +127,9 @@ public class Listener implements Runnable {
 			server = new MyServerSocketFactory().createServerSocket(port);
 			if (server == null)
 				return false;
+			if(protocol.toString().equals("SMB")) {
+				((SMB) protocol).setIP(Hostage.getContext().getSharedPreferences(Hostage.getContext().getString(R.string.connection_info), Hostage.MODE_PRIVATE).getString(Hostage.getContext().getString(R.string.connection_info_internal_ip), ""));
+			}
 			(this.thread = new Thread(this)).start();
 			running = true;
 			service.notifyUI(this.getClass().getName(),

+ 53 - 702
src/de/tudarmstadt/informatik/hostage/protocol/SMB.java

@@ -1,17 +1,14 @@
 package de.tudarmstadt.informatik.hostage.protocol;
 
-import java.nio.ByteBuffer;
 import java.security.SecureRandom;
 import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
 import java.util.List;
-import java.util.TimeZone;
 
-import android.content.Context;
 import de.tudarmstadt.informatik.hostage.Hostage;
 import de.tudarmstadt.informatik.hostage.R;
-import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+import de.tudarmstadt.informatik.hostage.protocol.SMBUtils.NBNS;
+import de.tudarmstadt.informatik.hostage.protocol.SMBUtils.NMB;
+import de.tudarmstadt.informatik.hostage.protocol.SMBUtils.SMBPacket;
 import de.tudarmstadt.informatik.hostage.wrapper.Packet;
 
 /**
@@ -23,12 +20,22 @@ import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  * @author Wulf Pfeiffer
  */
 public class SMB implements Protocol {
+	// 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;
+	
 	/**
-	 * Represents the states of the protocol
+	 * Denotes in which state the protocol is right now
 	 */
-	private static enum STATE {
-		NONE, CONNECTED, AUTHENTICATED, LISTING, DISCONNECTED, CLOSED
-	}
+	private STATE state = STATE.NONE;
+	private byte[] lastMessage;
 
 	// version stuff
 	private String[][] possibleSmbVersions = {
@@ -37,70 +44,30 @@ public class SMB implements Protocol {
 			{ "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" },
-			{ "Windows 2002 Service Pack 2", "Windows 2002 5.1"}
+			{ "Windows 2002 Service Pack 2", "Windows 2002 5.1" }
 	};
-
+	
 	/**
-	 * Converts the current system time into a byte[] with windows specific time
-	 * 
-	 * @return current system time in windows format as byte[]
+	 * Represents the states of the protocol
 	 */
-	private static byte[] getTimeInBytes() {
-		long time = System.currentTimeMillis();
-		Calendar calend = Calendar.getInstance();
-		calend.setTimeZone(TimeZone.getTimeZone("UTC"));
-		calend.set(1601, 0, 01, 00, 00, 00);
-		time -= calend.getTimeInMillis();
-		time *= 10000;
-
-		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--) {
-			timeInWindowsBytes[i] = (byte) (timeInBytes[j] & 0xff);
-		}
-
-		return timeInWindowsBytes;
+	private static enum STATE {
+		NONE, CONNECTED, AUTHENTICATED, LISTING, DISCONNECTED, CLOSED
 	}
-
-	/**
-	 * Converts the current timezone into a byte[] with windows specific format
-	 * 
-	 * @return current timezone in windows format as byte[]
-	 */
-	private static byte[] getTimeZoneInBytes() {
-		// get current timezone offset in minutes
-		Integer offset = new GregorianCalendar().getTimeZone().getRawOffset() / 1000 / 60; 
-		char[] offsetChars = Integer.toBinaryString(offset).toCharArray();
-		boolean invert = false;
-		for (int i = offsetChars.length - 1; i > -1; i--) {
-			if (!invert && offsetChars[i] == '1') {
-				invert = true;
-			} else if (invert) {
-				offsetChars[i] = (offsetChars[i] == '0') ? '1' : '0';
-			}
-		}
-		char[] extendedChars = new char[31];
-		for (int i = 0; i < extendedChars.length - offsetChars.length; i++) {
-			extendedChars[i] = '1';
-		}
-		for (int i = 0; i < offsetChars.length; i++) {
-			extendedChars[i + extendedChars.length - offsetChars.length] = offsetChars[i];
-		}
-		int timezone = Integer.parseInt(new String(extendedChars), 2);
-		byte[] timezoneBytes = new byte[2];
-		timezoneBytes[1] = (byte) (timezone >> 8);
-		timezoneBytes[0] = (byte) (timezone);
-		return timezoneBytes;
+	
+	public void setIP(String ip) {
+//		new NMB(ip).start();
 	}
 
 	private String[] initServerVersion() {
+		System.out.println("hi");
 		String sharedPreferencePath = Hostage.getContext().getString(
 				R.string.shared_preference_path);
+		System.out.println(sharedPreferencePath);
 		String profile = Hostage
 				.getContext()
 				.getSharedPreferences(sharedPreferencePath,
-						Context.MODE_PRIVATE).getString("os", "");
+						Hostage.MODE_PRIVATE).getString("os", "");
+		System.out.println(profile);
 		if (profile.equals("Windows 7")) {
 			return possibleSmbVersions[0];
 		} else if (profile.equals("Windows 8")) {
@@ -114,57 +81,13 @@ public class SMB implements Protocol {
 		} else if (profile.equals("Windows XP")) {
 			return possibleSmbVersions[5];
 		} else {
-			return possibleSmbVersions[new SecureRandom()
-					.nextInt(possibleSmbVersions.length)];
+			return possibleSmbVersions[new SecureRandom().nextInt(possibleSmbVersions.length)];
 		}
 	}
-
-	/**
-	 * Denotes in which state the protocol is right now
-	 */
-	private STATE state = STATE.NONE;
-
-	private byte[] lastMessage;
-
-	private byte[] serverName = HelperUtils.fillWithZero(HelperUtils
-			.getRandomString(16, true).getBytes());
-
+	
+	//required to be declared down here, do not change position over initServerVersion() and possibleServerVersions!!
 	private 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];
-	// 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;
+	private SMBPacket smbPacket = new SMBPacket(serverVersion);
 
 	@Override
 	public int getPort() {
@@ -185,72 +108,72 @@ public class SMB implements Protocol {
 	public List<Packet> processMessage(Packet requestPacket) {
 		if (requestPacket != null)
 			lastMessage = requestPacket.getBytes();
-		parseMessageHeader(lastMessage);
-		byte smbCommand = getSmbCommand();
+		smbPacket.prepareNextResponse(lastMessage);
+		byte smbCommand = smbPacket.getSmbCommand();
 		List<Packet> responsePackets = new ArrayList<Packet>();
 
 		switch (state) {
 		case NONE:
 			if (smbCommand == SMB_COM_NEGOTIATE) {
 				state = STATE.CONNECTED;
-				responsePackets.add(getNego());
+				responsePackets.add(new Packet(smbPacket.getNego()));
 			} else {
 				state = STATE.DISCONNECTED;
-				responsePackets.add(getTreeDisc());
+				responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			}
 			break;
 		case CONNECTED:
 			if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
-				responsePackets.add(getSessSetup());
+				responsePackets.add(new Packet(smbPacket.getSessSetup()));
 			} else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
 				state = STATE.AUTHENTICATED;
-				responsePackets.add(getTreeCon());
+				responsePackets.add(new Packet(smbPacket.getTreeCon()));
 			} else {
 				state = STATE.DISCONNECTED;
-				responsePackets.add(getTreeDisc());
+				responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			}
 			break;
 		case AUTHENTICATED:
 			if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
 				state = STATE.LISTING;
-				responsePackets.add(getNTCreate());
+				responsePackets.add(new Packet(smbPacket.getNTCreate()));
 			} else if (smbCommand == SMB_COM_ECHO) {
-				responsePackets.add(getEcho());
+				responsePackets.add(new Packet(smbPacket.getEcho()));
 			} else if (smbCommand == SMB_COM_TRANSACTION2) {
-				responsePackets.add(getTrans2());
+				responsePackets.add(new Packet(smbPacket.getTrans2()));
 			} else if (smbCommand == SMB_COM_CLOSE) {
-				responsePackets.add(getClose());
+				responsePackets.add(new Packet(smbPacket.getClose()));
 			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
 				state = STATE.CLOSED;
-				responsePackets.add(getTreeDisc());
+				responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			} else {
 				state = STATE.DISCONNECTED;
-				responsePackets.add(getTreeDisc());
+				responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			}
 			break;
 		case LISTING:
 			if (smbCommand == SMB_COM_TRANSACTION) {
-				responsePackets.add(getTrans());
+				responsePackets.add(new Packet(smbPacket.getTrans()));
 			} else if (smbCommand == SMB_COM_CLOSE) {
-				responsePackets.add(getClose());
+				responsePackets.add(new Packet(smbPacket.getClose()));
 			} else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
 				state = STATE.CLOSED;
-				responsePackets.add(getTreeDisc());
+				responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			} else if (smbCommand == SMB_COM_NEGOTIATE) {
 				state = STATE.CONNECTED;
-				responsePackets.add(getNego());
+				responsePackets.add(new Packet(smbPacket.getNego()));
 			} else {
 				state = STATE.DISCONNECTED;
-				responsePackets.add(getTreeDisc());
+				responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			}
 			break;
 		case DISCONNECTED:
 			state = STATE.CLOSED;
-			responsePackets.add(getTreeDisc());
+			responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 			break;
 		default:
 			state = STATE.CLOSED;
-			responsePackets.add(getTreeDisc());
+			responsePackets.add(new Packet(smbPacket.getTreeDisc()));
 		}
 		return responsePackets;
 	}
@@ -264,576 +187,4 @@ public class SMB implements Protocol {
 	public TALK_FIRST whoTalksFirst() {
 		return TALK_FIRST.CLIENT;
 	}
-
-	/**
-	 * 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 };
-	}
-
-	/**
-	 * Builds the close packet
-	 * 
-	 * @return close packet
-	 */
-	private Packet getClose() {
-		byte[] wordCount = { 0x00 };
-		byte[] byteCount = { 0x00, 0x00 };
-
-		smbCommand = new byte[] { 0x04 };
-
-		byte[] response = HelperUtils.concat(wordCount, byteCount);
-
-		return new Packet(wrapNetbios(wrapHeader(response)));
-	}
-
-	/**
-	 * 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;
-	}
-
-	/**
-	 * 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 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)));
-	}
-
-	/**
-	 * 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 session setup packet
-	 * 
-	 * @ret urn session setup packet
-	 */
-	private Packet getSessSetup() {
-		if (authenticateNext) {
-			return new Packet(getSetupAuth());
-		} else {
-			authenticateNext = true;
-			return new Packet(getSetupChal());
-		}
-	}
-
-	/**
-	 * 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());
-
-		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[] response = HelperUtils.concat(wordCount, andXCommand, reserved,
-				andXOffset, action, secBlobLength, byteCount, secBlob, nativOS,
-				nativLanMngr);
-		return wrapNetbios(wrapHeader(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);
-		}
-		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));
-	}
-
-	/**
-	 * Returns the command number from the current message
-	 * 
-	 * @return command number
-	 */
-	private byte getSmbCommand() {
-		return smbCommand[0];
-	}
-
-	/**
-	 * 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);
-
-			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)));
-	}
-
-	/**
-	 * 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;
-	}
-
-	/**
-	 * 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 = { 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);
-		}
-
-		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 };
-
-		smbCommand[0] = 0x71;
-
-		byte[] response = HelperUtils.concat(wordCount, byteCount);
-
-		return new Packet(wrapNetbios(wrapHeader(response)));
-	}
-
-	/**
-	 * Breaks a message from the client down into its components
-	 * 
-	 * @param message
-	 *            that is analyzed
-	 */
-	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 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);
-	}
-
-	/**
-	 * Wraps the Netbios header around a response
-	 * 
-	 * @param response
-	 *            that is wrapped
-	 * @return wrapped response
-	 */
-	private byte[] wrapNetbios(byte[] response) {
-		byte[] netbios = { 0x00 };
-		// allocate(4) because int is 4 bytes long
-		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();
-		// only bytes 1-3 needed, byte 0 is not  needed
-		byte[] netbiosLength = { buffer[1], buffer[2], buffer[3] }; 
-		return HelperUtils.concat(netbios, netbiosLength, response);
-	}
-
 }

+ 103 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/NBDS.java

@@ -0,0 +1,103 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+import java.nio.ByteBuffer;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+
+public class NBDS {
+	
+	private byte[] type;
+	private byte[] flags;
+	private byte[] id;
+	private byte[] srcIP;
+	private byte[] srcPort;
+	private byte[] length;
+	private byte[] offset;
+	private byte[] srcName;
+	private byte[] dstName;
+	private SMBPacket smb;
+	private SMBMailSlot smbMailSlot;
+	private MicrosoftWindowsBrowser microsoftWindowsBrowser;
+	
+	public NBDS(byte[] transactID, byte[] ip, byte[] addr, String src, String dst) {
+		type = new byte[]{0x11};
+		flags = new byte[]{0x0a};
+		id = transactID;
+		srcIP = addr;
+		srcPort = new byte[]{0x00, (byte) 0x8a};
+		offset = new byte[]{0x00, 0x00};
+		length = new byte[2];
+		srcName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(src.getBytes()), Service.WORKSTATION);
+		dstName = NMBStringCoder.wrapNBNSName(NMBStringCoder.encodeNBNSName(dst.getBytes()), Service.LOCAL_MASTER_BROWSER);
+		smb = new SMBPacket(null);
+		smb.prepareNextResponse();
+		smbMailSlot = new SMBMailSlot();
+		microsoftWindowsBrowser = new MicrosoftWindowsBrowser(src);
+		byte[] buffer = HelperUtils.concat(srcName, dstName, smb.getTrans(), smbMailSlot.getBytes(), microsoftWindowsBrowser.getBytes());
+		byte[] lengthBuffer = ByteBuffer.allocate(4).putInt(buffer.length).array();
+		length[0] = lengthBuffer[2];
+		length[1] = lengthBuffer[3];
+	}
+	
+	public byte[] getBytes() {
+		return HelperUtils.concat(type, flags, id, srcIP, srcPort, length,
+				offset, srcName, dstName, smb.getTrans(), smbMailSlot.getBytes(), microsoftWindowsBrowser.getBytes());
+	}
+
+	private class SMBMailSlot {
+		private byte[] opcode;
+		private byte[] priority;
+		private byte[] smbclass;
+		private byte[] size;
+		private byte[] name;
+		
+		public SMBMailSlot() {
+			opcode = new byte[]{0x01, 0x00};
+			priority = new byte[]{0x01, 0x00};
+			smbclass = new byte[]{0x02, 0x00};
+			size = new byte[]{0x3e, 0x00};
+			name = HelperUtils.concat("\\MAILSLOT\\BROWSE".getBytes(), new byte[]{0x00}); 
+		}
+		
+		public byte[] getBytes() {
+			return HelperUtils.concat(opcode, priority, smbclass, size, name);
+		}
+	}
+	
+	private class MicrosoftWindowsBrowser {
+		private byte[] command;
+		private byte[] updateCount;
+		private byte[] updatePeriodicity;
+		private byte[] hostName;
+		private byte[] osMajorVersion;
+		private byte[] osMinorVersion;
+		private byte[] serverType;
+		private byte[] browserProtocolMajorVer;
+		private byte[] browserProtocolMinorVer;
+		private byte[] signature;
+		private byte[] hostComment;
+		
+		public MicrosoftWindowsBrowser(String name) {
+			command = new byte[]{0x01};
+			updateCount = new byte[]{0x00};
+			updatePeriodicity = new byte[]{0x60, (byte) 0xea, 0x00, 0x00};
+			hostName = HelperUtils.concat(name.getBytes(),
+					new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+			osMajorVersion = new byte[]{0x04};
+			osMinorVersion = new byte[]{0x09};
+			serverType = new byte[]{0x03, (byte) 0x9a, (byte) 0x81, 0x00};
+			browserProtocolMajorVer = new byte[]{0x0f};
+			browserProtocolMinorVer = new byte[]{0x01};
+			signature = new byte[]{0x55, (byte) 0xaa};
+			hostComment = HelperUtils.concat("Samba Server".getBytes(), new byte[]{0x00});
+		}
+		
+		public byte[] getBytes() {
+			return HelperUtils.concat(command, updateCount, updatePeriodicity,
+					hostName, osMajorVersion, osMinorVersion, serverType,
+					browserProtocolMajorVer, browserProtocolMinorVer,
+					signature, hostComment);
+		}
+	}
+}

+ 176 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/NBNS.java

@@ -0,0 +1,176 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+import java.nio.ByteBuffer;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+
+public class NBNS {
+	
+	private byte[] transactID;
+	private byte[] flags;
+	private byte[] questions;
+	private byte[] answerRRs;
+	private byte[] authorityRRs;
+	private byte[] additionalRRs;
+	private byte[] payload;
+	private byte[] additional;
+	private byte[] addr;
+	private byte[] name;
+	private int type;
+	private int service;
+	
+	public NBNS(byte[] packet) {
+		transactID = new byte[]{packet[0], packet[1]};
+		flags = new byte[]{packet[2], packet[3]};
+		questions = new byte[]{packet[4], packet[5]};
+		answerRRs = new byte[]{packet[6], packet[7]};
+		authorityRRs = new byte[]{packet[8], packet[9]};
+		additionalRRs = new byte[]{packet[10], packet[11]};
+		int length = 0;
+		for (int i = 12; i < packet.length; i++, length++) {
+			if (packet[i] == 0x01) {
+				length++;
+				break;
+			}
+		}
+		payload = new byte[length];
+		for (int i = 0; i < payload.length; i++) {
+			payload[i] = packet[i+12];
+		}
+		additional = new byte[packet.length-12-length];
+		for (int i = 0; i < additional.length; i++) {
+			additional[i] = packet[i+12+length];
+		}
+	}
+	
+	public NBNS(byte[] transactID, String addr) {
+		this.transactID = transactID;
+		addressToBytes(addr);
+	}
+	
+	public NBNS(byte[] transactID, int type, int service, String name, String addr) {
+		this(transactID, addr);
+		this.type = type;
+		this.service = service;
+		setName(name);
+	}
+	
+	private void preparePacket() {
+		switch (type) {
+		case Type.REGISTRATION_UNIQUE:
+			prepareRegistrationPacket();
+			break;
+		case Type.REGISTRATION_GROUP:
+			prepareRegistrationPacket();
+			break;
+		case Type.NAME_QUERY:
+			prepareNameQueryPacket();
+			break;
+		default:
+		}
+	}
+	
+	private void prepareRegistrationPacket() {
+		flags = new byte[]{0x29, 0x10};
+		questions = new byte[]{0x00, 0x01};
+		answerRRs = new byte[]{0x00, 0x00};
+		authorityRRs = new byte[]{0x00, 0x00};
+		additionalRRs = new byte[]{0x00, 0x01};
+		payload = getPayload();
+		additional = getAdditionalRecords();
+	}
+	
+	private void prepareNameQueryPacket() {
+		flags = new byte[] {0x01, 0x10};
+		questions = new byte[]{0x00, 0x01};
+		answerRRs = new byte[]{0x00, 0x00};
+		authorityRRs = new byte[]{0x00, 0x00};
+		additionalRRs = new byte[]{0x00, 0x00};
+		payload = getPayload();
+	}
+	
+	private byte[] getPayload() {
+		byte[] payload = NMBStringCoder.wrapNBNSName(this.name, service);
+		byte[] type = {0x00, 0x20};
+		byte[] nbnsclass = {0x00, 0x01};
+		return HelperUtils.concat(payload, type, nbnsclass);
+	}
+		
+	private void addressToBytes(String addrString) {
+		String[] addrParts = addrString.split("\\.");
+		addr = new byte[4];
+		addr[0] = (byte)Integer.parseInt(addrParts[0]);
+		addr[1] = (byte)Integer.parseInt(addrParts[1]);
+		addr[2] = (byte)Integer.parseInt(addrParts[2]);
+		addr[3] = (byte)Integer.parseInt(addrParts[3]);
+	}
+	
+	public static byte[] getServiceBytes(int service) {
+		switch (service) {
+		case Service.SERVER:
+			return new byte[]{0x43, 0x41};
+		case Service.MESSENGER:
+			return new byte[]{0x41, 0x44};
+		case Service.WORKSTATION:
+			return new byte[]{0x41, 0x41};
+		case Service.BROWSER_ELECTION:
+			return new byte[]{0x42, 0x4f};
+		case Service.LOCAL_MASTER_BROWSER:
+			return new byte[]{0x42, 0x4e};
+		default:
+			return new byte[]{0x43, 0x41};
+		}
+	}
+
+	private byte[] getAdditionalRecords() {
+		byte[] name = {(byte) 0xc0, 0x0c};
+		byte[] type = {0x00, 0x20};
+		byte[] nbnsclass = {0x00, 0x01};
+		byte[] timeToLive = {0x00, 0x00, 0x00, 0x00};
+		byte[] nameFlags = ((this.type == Type.REGISTRATION_UNIQUE) ? new byte[]{0x00, 0x00} : new byte[]{0x08, 0x00});
+		byte[] buffer = ByteBuffer.allocate(4).putInt(nameFlags.length + addr.length).array();
+		byte[] length = {buffer[2], buffer[3]};
+		return HelperUtils.concat(name, type, nbnsclass, timeToLive, length, nameFlags, addr);
+	}
+	
+	public byte[] getNextPacket() {
+		preparePacket();
+		transactID[1] += 0x01;
+		return getBytes();
+	}
+
+	public byte[] getBytes() {
+		return HelperUtils.concat(transactID, flags, questions, answerRRs, authorityRRs, additionalRRs, payload, additional);
+	}
+
+	public void setName(String name) {
+		this.name = name.getBytes();
+		this.name = NMBStringCoder.encodeNBNSName(this.name);
+	}
+
+	public void setType(int type) {
+		this.type = type;
+	}
+
+	public void setService(int service) {
+		this.service = service;
+	}
+
+	public byte[] getAndIncrementTransactID() {
+		byte[] response = new byte[2];
+		response[0] = transactID[0];
+		response[1] = transactID[1];
+		transactID[1] += 0x01;
+		return response;
+	}
+
+	public byte[] getAddr() {
+		return addr;
+	}
+
+	public byte[] getName() {
+		return name;
+	}
+	
+}

+ 96 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/NMB.java

@@ -0,0 +1,96 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class NMB extends Thread {
+	
+	public static void main(String[] args) {
+		NMB nbns = new NMB("192.168.178.104", "ABCDEFG", "WORKGROUP");
+		nbns.start();
+	}
+	
+	private DatagramSocket nbnsSocket;
+	private DatagramSocket nbdsSocket;
+	private DatagramPacket packet;
+	private String ip;
+	private String[] ipParts;
+	private InetAddress dst;
+	private int nbnsPort = 137;
+	private int nbdsPort = 138;
+	private String username;
+	private String workgroup;
+	
+	public NMB(String ip, String username, String workgroup) {
+		super();
+		try {
+			this.username = username;
+			this.workgroup = workgroup;
+			nbnsSocket = new DatagramSocket(nbnsPort);
+			nbdsSocket = new DatagramSocket(nbdsPort);
+			this.ip = ip;
+			ipParts = ip.split("\\.");
+			String newHostAddr = ipParts[0] + "." + ipParts[1] + "." + ipParts[2] + ".255";
+			dst = InetAddress.getByName(newHostAddr);
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private void sendPacket(NBNS nbns) {
+		try {
+			byte[] packetBytes = nbns.getNextPacket();
+			packet = new DatagramPacket(packetBytes, packetBytes.length, dst, nbnsPort);
+			nbnsSocket.send(packet);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private void sendPacket(NBDS nbds) {
+		try {
+			byte[] packetBytes = nbds.getBytes();
+			packet = new DatagramPacket(packetBytes, packetBytes.length, dst, nbdsPort);
+			nbnsSocket.send(packet);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private void registrate() {
+		NBNS nbns = new NBNS(new byte[]{0x50, 0x00}, Type.REGISTRATION_UNIQUE, Service.SERVER, username, ip);
+		sendPacket(nbns);
+		
+		nbns.setService(Service.MESSENGER);
+		sendPacket(nbns);
+				
+		nbns.setService(Service.WORKSTATION);
+		sendPacket(nbns);
+			
+		nbns.setName(workgroup);
+		nbns.setType(Type.REGISTRATION_GROUP);
+		sendPacket(nbns);
+		
+		nbns.setService(Service.BROWSER_ELECTION);
+		sendPacket(nbns);
+		
+		NBDS nbds = new NBDS(new byte[]{0x50, 0x06}, nbns.getAndIncrementTransactID(), nbns.getAddr(), username, workgroup);
+		sendPacket(nbds);
+		
+		nbns.setType(Type.NAME_QUERY);
+		nbns.setService(Service.LOCAL_MASTER_BROWSER);
+		sendPacket(nbns);
+	}
+
+	public void run() {
+		registrate();
+		nbnsSocket.close();
+		nbdsSocket.close();
+	}
+	
+}

+ 58 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/NMBStringCoder.java

@@ -0,0 +1,58 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+
+public class NMBStringCoder {
+
+	public static String decodeNBNSName(byte[] name) {
+		byte a_ascii = (byte) 'A';
+		byte[] reducedA = new byte[name.length];
+		for (int i = 0; i < name.length; i++) {
+			reducedA[i] = (byte)(name[i] - a_ascii);
+		}
+		byte[] converted = new byte[reducedA.length / 2];
+		for (int i = 0, j = 0; i < name.length && j < converted.length; i+=2, j++) {
+			byte b1 = (byte) (reducedA[i]<<4);
+			byte b2 = reducedA[i+1];
+			converted[j] = (byte) (b1 | b2);
+		}
+		return new String(converted);
+	}
+	
+	public static byte[] encodeNBNSName(byte[] name) {
+		byte a_ascii = (byte) 'A';
+		byte[] bytes = name;
+		byte[] converted = new byte[bytes.length * 2];
+		for (int i = 0, j = 0; i < bytes.length && j < converted.length; i++, j+=2) {
+			converted[j] = (byte)(bytes[i]>>4);
+			converted[j+1] = (byte)(bytes[i] & 0x0F);
+		}
+		byte[] addedA = new byte[converted.length];
+		for (int i = 0; i < converted.length; i++) {
+			addedA[i] = (byte) (converted[i] + a_ascii);
+		}
+		return addedA;
+	}
+	
+	public static byte[] wrapNBNSName(byte[] name, int service) {
+		byte[] nameStart = {0x20};
+		byte[] namePadding = null;
+		if (name.length < 32) {
+			int paddingLen = 32 - name.length;
+			namePadding = new byte[paddingLen];
+			for (int i = 0; i < namePadding.length; i+=2) {
+				if (i == namePadding.length-2) {
+					byte[] serviceBytes = NBNS.getServiceBytes(service);
+					namePadding[i] = serviceBytes[0];
+					namePadding[i+1] = serviceBytes[1];
+				} else {
+					namePadding[i] = 0x43;
+					namePadding[i+1] = 0x041;
+				}
+			}
+		}
+		byte[] nameEnd = {0x00};
+		return HelperUtils.concat(nameStart, name, namePadding, nameEnd);
+	}
+}

+ 701 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/SMBPacket.java

@@ -0,0 +1,701 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+import java.nio.ByteBuffer;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
+
+/**
+ * SMBPacket
+ * 
+ * @author Wulf Pfeiffer
+ */
+public class SMBPacket {
+	
+	private String[] serverVersion;
+	private byte[] serverName = HelperUtils.fillWithZero(HelperUtils
+			.getRandomString(16, true).getBytes());
+	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];
+	
+	public SMBPacket(String[] serverVersion) {
+		this.serverVersion = serverVersion;
+	}
+	
+	public void prepareNextResponse() {
+		serverComp = new byte[] { (byte) 0xff, 0x53, 0x4d, 0x42 };
+		smbCommand = new byte[] { 0x25 };
+		ntStat = new byte[] { 0x00, 0x00, 0x00, 0x00 };
+		// | 0x80 for mark response bit
+		smbFlags = new byte[] { 0x00 }; 
+		smbFlags2 = new byte[] { 0x00, 0x00 };
+		processIDHigh = new byte[] { 0x00, 0x00 };
+		signature = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+		reserved = new byte[] { 0x00, 0x00 };
+		treeID = new byte[] { 0x00, 0x00 };
+		processID = new byte[] { 0x00, 0x00 };
+		userID = new byte[] { 0x00, 0x00 };
+		multiplexID = new byte[] { 0x00, 0x00 };
+	}
+	
+	public void prepareNextResponse(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] };
+		// | 0x80 for mark response bit
+		smbFlags = new byte[] { (byte) (message[13] | 0x80) }; 
+		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 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);
+	}
+
+	/**
+	 * Wraps the Netbios header around a response
+	 * 
+	 * @param response
+	 *            that is wrapped
+	 * @return wrapped response
+	 */
+	private byte[] wrapNetbios(byte[] response) {
+		byte[] netbios = { 0x00 };
+		// allocate(4) because int is 4 bytes long
+		byte[] buffer = ByteBuffer.allocate(4).putInt(response.length).array();
+		// only bytes 1-3 needed, byte 0 is not  needed
+		byte[] netbiosLength = { buffer[1], buffer[2], buffer[3] }; 
+		return HelperUtils.concat(netbios, netbiosLength, 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++;
+			}
+		}
+		return new byte[] { 0x00, 0x00 };
+	}
+
+	/**
+	 * Builds the close packet
+	 * 
+	 * @return close packet
+	 */
+	public byte[] getClose() {
+		byte[] wordCount = { 0x00 };
+		byte[] byteCount = { 0x00, 0x00 };
+
+		smbCommand = new byte[] { 0x04 };
+
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
+
+		return wrapNetbios(wrapHeader(response));
+	}
+
+	/**
+	 * Builds the DCERPC packet
+	 * 
+	 * @return DCERPC packet
+	 */
+	public 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;
+	}
+
+	/**
+	 * Builds the echo packet
+	 * 
+	 * @return echo packet
+	 */
+	public byte[] 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 wrapNetbios(wrapHeader(response));
+	}
+
+	/**
+	 * Builds the negotiate packet
+	 * 
+	 * @return negotiate packet
+	 */
+	public byte[] 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 wrapNetbios(wrapHeader(response));
+	}
+
+	/**
+	 * Builds the nt create packet
+	 * 
+	 * @return nt create packet
+	 */
+	public byte[] 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 wrapNetbios(wrapHeader(response));
+	}
+
+	/**
+	 * Builds the session setup packet
+	 * 
+	 * @ret urn session setup packet
+	 */
+	public byte[] getSessSetup() {
+		if (authenticateNext) {
+			return getSetupAuth();
+		} else {
+			authenticateNext = true;
+			return getSetupChal();
+		}
+	}
+
+	/**
+	 * 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());
+
+		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[] response = HelperUtils.concat(wordCount, andXCommand, reserved,
+				andXOffset, action, secBlobLength, byteCount, secBlob, nativOS,
+				nativLanMngr);
+		return wrapNetbios(wrapHeader(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);
+		}
+		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));
+	}
+
+	/**
+	 * Returns the command number from the current message
+	 * 
+	 * @return command number
+	 */
+	public byte getSmbCommand() {
+		return smbCommand[0];
+	}
+
+	/**
+	 * Builds the trans packet
+	 * 
+	 * @return trans packet
+	 */
+	public byte[] getTrans() {
+		byte[] transSub = getTransSub();
+		byte[] response = null;
+		
+		if (transSub[0] == (byte) 0xff) { // for NMB in host announcement, NOT smb protocol
+			System.out.println("Hi");
+			byte[] wordCount = { 0x11 };
+			byte[] totalParamCount = { 0x00, 0x00 };
+			byte[] totalDataCount = { 0x2d, 0x00 };
+			byte[] maxParamCount = { 0x00, 0x00 };
+			byte[] maxDataCount = { 0x00, 0x00 };
+			byte[] maxSetupCount = { 0x00 };
+			byte[] reserved = { 0x00 };
+			byte[] flags = { 0x00, 0x00 };
+			byte[] timeout = { 0x00, 0x00, 0x00, 0x00 };
+			byte[] reserved2 = { 0x00, 0x00 };
+			byte[] paramCount = { 0x00, 0x00 };
+			byte[] paramOffset = { 0x00, 0x00 };
+			byte[] dataCount = { 0x2d, 0x00 };
+			byte[] dataOffset = { 0x56, 0x00 };
+			byte[] setupCount = { 0x03 };
+			byte[] reserved3 = { 0x00 };
+			// no netbios header required for NMB!!
+			return wrapHeader(HelperUtils.concat(wordCount, totalParamCount, totalDataCount,
+					maxParamCount, maxDataCount, maxSetupCount, reserved, flags, timeout, reserved2,
+					paramCount, paramOffset, dataCount, dataOffset, setupCount, reserved3));
+		} else 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);
+
+			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 wrapNetbios(wrapHeader(response));
+	}
+
+	/**
+	 * Builds the trans2 packet
+	 * 
+	 * @return trans2 packet
+	 */
+	public byte[] 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 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 && message != null)
+			transSub = new byte[] { 0x00, message[90] };
+		else if (smbCommand[0] == 0x25 && message == null)
+			transSub = new byte[] { (byte) 0xff };
+		else
+			transSub = new byte[] { 0x00, 0x00 };
+		return transSub;
+	}
+
+	/**
+	 * Builds the tree connect packet
+	 * 
+	 * @return tree connect packet
+	 */
+	public byte[] 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 = { 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);
+		}
+
+		return wrapNetbios(wrapHeader(response));
+	}
+
+	/**
+	 * Builds the tree disconnect packet
+	 * 
+	 * @return tree disconnect packet
+	 */
+	public byte[] getTreeDisc() {
+		byte[] wordCount = { 0x00 };
+		byte[] byteCount = { 0x00, 0x00 };
+
+		smbCommand[0] = 0x71;
+
+		byte[] response = HelperUtils.concat(wordCount, byteCount);
+
+		return wrapNetbios(wrapHeader(response));
+	}
+	
+
+	/**
+	 * Converts the current system time into a byte[] with windows specific time
+	 * 
+	 * @return current system time in windows format as byte[]
+	 */
+	private static byte[] getTimeInBytes() {
+		long time = System.currentTimeMillis();
+		Calendar calend = Calendar.getInstance();
+		calend.setTimeZone(TimeZone.getTimeZone("UTC"));
+		calend.set(1601, 0, 01, 00, 00, 00);
+		time -= calend.getTimeInMillis();
+		time *= 10000;
+
+		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--) {
+			timeInWindowsBytes[i] = (byte) (timeInBytes[j] & 0xff);
+		}
+
+		return timeInWindowsBytes;
+	}
+
+	/**
+	 * Converts the current timezone into a byte[] with windows specific format
+	 * 
+	 * @return current timezone in windows format as byte[]
+	 */
+	private static byte[] getTimeZoneInBytes() {
+		// get current timezone offset in minutes
+		Integer offset = new GregorianCalendar().getTimeZone().getRawOffset() / 1000 / 60; 
+		char[] offsetChars = Integer.toBinaryString(offset).toCharArray();
+		boolean invert = false;
+		for (int i = offsetChars.length - 1; i > -1; i--) {
+			if (!invert && offsetChars[i] == '1') {
+				invert = true;
+			} else if (invert) {
+				offsetChars[i] = (offsetChars[i] == '0') ? '1' : '0';
+			}
+		}
+		char[] extendedChars = new char[31];
+		for (int i = 0; i < extendedChars.length - offsetChars.length; i++) {
+			extendedChars[i] = '1';
+		}
+		for (int i = 0; i < offsetChars.length; i++) {
+			extendedChars[i + extendedChars.length - offsetChars.length] = offsetChars[i];
+		}
+		int timezone = Integer.parseInt(new String(extendedChars), 2);
+		byte[] timezoneBytes = new byte[2];
+		timezoneBytes[1] = (byte) (timezone >> 8);
+		timezoneBytes[0] = (byte) (timezone);
+		return timezoneBytes;
+	}
+
+}

+ 9 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/Service.java

@@ -0,0 +1,9 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+public class Service {
+	public static final int SERVER = 0;
+	public static final int MESSENGER = 1;
+	public static final int WORKSTATION = 2;
+	public static final int BROWSER_ELECTION = 3;
+	public static final int LOCAL_MASTER_BROWSER = 4;
+}

+ 7 - 0
src/de/tudarmstadt/informatik/hostage/protocol/SMBUtils/Type.java

@@ -0,0 +1,7 @@
+package de.tudarmstadt.informatik.hostage.protocol.SMBUtils;
+
+public class Type {
+	public static final int REGISTRATION_UNIQUE = 0;
+	public static final int REGISTRATION_GROUP = 1;
+	public static final int NAME_QUERY = 2;
+}

+ 7 - 5
src/de/tudarmstadt/informatik/hostage/wrapper/Packet.java

@@ -11,6 +11,7 @@ import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
 public class Packet {
 
 	private byte[] payload;
+	private boolean createdWithBytes;
 
 	/**
 	 * Constructs Packet from byte[]
@@ -20,6 +21,7 @@ public class Packet {
 	 */
 	public Packet(byte[] payload) {
 		this.payload = payload;
+		createdWithBytes = true;
 	}
 
 	/**
@@ -30,6 +32,7 @@ public class Packet {
 	 */
 	public Packet(String payload) {
 		this.payload = payload.getBytes();
+		createdWithBytes = false;
 	}
 
 	/**
@@ -53,12 +56,11 @@ public class Packet {
 	 */
 	@Override
 	public String toString() {
-		for (int i = 0; i < payload.length; ++i) {
-			if (((char) payload[i]) < 9) {
-				return HelperUtils.bytesToHexString(payload);
-			}
+		if (createdWithBytes) {
+			return HelperUtils.bytesToHexString(payload);
+		} else {
+			return new String(payload);
 		}
-		return new String(payload);
 	}
 
 }