SMB.java 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package de.tudarmstadt.informatik.hostage.protocol;
  2. import java.security.SecureRandom;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import android.content.SharedPreferences;
  6. import android.preference.PreferenceManager;
  7. import de.tudarmstadt.informatik.hostage.Hostage;
  8. import de.tudarmstadt.informatik.hostage.R;
  9. import de.tudarmstadt.informatik.hostage.commons.HelperUtils;
  10. import de.tudarmstadt.informatik.hostage.protocol.smbutils.NBDSType;
  11. import de.tudarmstadt.informatik.hostage.protocol.smbutils.NBNS;
  12. import de.tudarmstadt.informatik.hostage.protocol.smbutils.NBNSType;
  13. import de.tudarmstadt.informatik.hostage.protocol.smbutils.NMB;
  14. import de.tudarmstadt.informatik.hostage.protocol.smbutils.SMBPacket;
  15. import de.tudarmstadt.informatik.hostage.wrapper.Packet;
  16. /**
  17. * SMB protocol. It can handle the following requests: Negotiate Protocol
  18. * Request, Session Setup AndX Request, Tree Connect AndX Request, NT Create
  19. * AndX Request, Bind, NetShareEnumAll, Close Request, Tree Disconnect Request,
  20. * Echo Request, Trans2 Request.
  21. *
  22. * @author Wulf Pfeiffer
  23. */
  24. public class SMB implements Protocol {
  25. // message constants
  26. private static final byte SMB_COM_CLOSE = 0x04;
  27. private static final byte SMB_COM_TRANSACTION = 0x25;
  28. private static final byte SMB_COM_ECHO = 0x2B;
  29. private static final byte SMB_COM_TRANSACTION2 = 0x32;
  30. private static final byte SMB_COM_TREE_DISCONNECT = 0x71;
  31. private static final byte SMB_COM_NEGOTIATE = 0x72;
  32. private static final byte SMB_COM_SESSION_SETUP_ANDX = 0x73;
  33. private static final byte SMB_COM_TREE_CONNECT_ANDX = 0x75;
  34. private static final byte SMB_COM_NT_CREATE_ANDX = (byte) 0xA2;
  35. /**
  36. * Denotes in which state the protocol is right now
  37. */
  38. private STATE state = STATE.NONE;
  39. private byte[] lastMessage;
  40. private NMB nmb;
  41. // version stuff
  42. private String[][] possibleSmbVersions = {
  43. { "Windows 7 Professional 7600", "Windows 7 Professional 6.1" },
  44. { "Windows 8 Enterprise 9200", "Windows 8 Enterprise 9200" },
  45. { "Windows Server 2008 R2 Enterprise 7600", "Windows Server 2008 R2 Enterprise 6.1" },
  46. { "Windows Server 2012 Standard 6.2", "Windows Server 2012 Standard 6.2" },
  47. { "Unix", "Samba" },
  48. { "Windows 2002 Service Pack 2", "Windows 2002 5.1" }
  49. };
  50. /**
  51. * Represents the states of the protocol
  52. */
  53. private static enum STATE {
  54. NONE, CONNECTED, AUTHENTICATED, LISTING, DISCONNECTED, CLOSED
  55. }
  56. public void setIP(String ip) {
  57. // TODO if porthack is working for UDP uncomment
  58. nmb = new NMB(ip, "BLIBLABLUB", "Workgroup");
  59. nmb.start();
  60. // nmb = new NMB(ip, new String(serverName), workgroup);
  61. // nmb.start();
  62. }
  63. private String[] initServerVersion() {
  64. String sharedPreferencePath = Hostage.getContext().getString(
  65. R.string.shared_preference_path);
  66. String profile = Hostage
  67. .getContext()
  68. .getSharedPreferences(sharedPreferencePath,
  69. Hostage.MODE_PRIVATE).getString("os", "");
  70. if(profile.equals("Windows XP")) {
  71. workgroup = "MSHOME";
  72. } else {
  73. workgroup = "WORKGROUP";
  74. }
  75. if (profile.equals("Windows 7")) {
  76. return possibleSmbVersions[0];
  77. } else if (profile.equals("Windows 8")) {
  78. return possibleSmbVersions[1];
  79. } else if (profile.equals("Windows Server 2008")) {
  80. return possibleSmbVersions[2];
  81. } else if (profile.equals("Windows Server 2012")) {
  82. return possibleSmbVersions[3];
  83. } else if (profile.equals("Linux")) {
  84. return possibleSmbVersions[4];
  85. } else if (profile.equals("Windows XP")) {
  86. return possibleSmbVersions[5];
  87. } else {
  88. return possibleSmbVersions[new SecureRandom().nextInt(possibleSmbVersions.length)];
  89. }
  90. }
  91. //required to be declared down here, do not change position over initServerVersion() and possibleServerVersions!!
  92. private String[] serverVersion = initServerVersion();
  93. private static byte[] serverName = HelperUtils.fillWithZero(HelperUtils
  94. .getRandomString(16, true).getBytes());
  95. private static String workgroup;
  96. private SMBPacket smbPacket = new SMBPacket(serverVersion, new String(serverName), workgroup);
  97. private int maxEchoPackets = initMaxPackets();
  98. private int receivedEchoPackets = 0;
  99. private int initMaxPackets() {
  100. int maxPackets;
  101. SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(Hostage.getContext());
  102. maxPackets = Integer.parseInt(prefs.getString("pref_timeout", "30")) / 5;
  103. return maxPackets;
  104. }
  105. @Override
  106. public int getPort() {
  107. return 445;
  108. }
  109. @Override
  110. public boolean isClosed() {
  111. return (state == STATE.CLOSED);
  112. }
  113. @Override
  114. public boolean isSecure() {
  115. return false;
  116. }
  117. //just for debugging purpose
  118. final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
  119. public static String bytesToHex(byte[] bytes) {
  120. char[] hexChars = new char[bytes.length * 2];
  121. for ( int j = 0; j < bytes.length; j++ ) {
  122. int v = bytes[j] & 0xFF;
  123. hexChars[j * 2] = hexArray[v >>> 4];
  124. hexChars[j * 2 + 1] = hexArray[v & 0x0F];
  125. }
  126. return new String(hexChars);
  127. }
  128. @Override
  129. public List<Packet> processMessage(Packet requestPacket) {
  130. if (requestPacket != null && requestPacket.getBytes().length != 0){
  131. lastMessage = requestPacket.getBytes();
  132. System.out.println("request packet " + bytesToHex(lastMessage));
  133. smbPacket.prepareNextResponse(lastMessage);
  134. }
  135. else{
  136. //something needs to be done, if there is no message
  137. smbPacket.prepareNextResponse(0);
  138. }
  139. byte smbCommand = smbPacket.getSmbCommand();
  140. byte[] response;
  141. List<Packet> responsePackets = new ArrayList<Packet>();
  142. if (smbCommand == SMB_COM_ECHO) {
  143. receivedEchoPackets++;
  144. } else {
  145. receivedEchoPackets = 0;
  146. }
  147. if (receivedEchoPackets == maxEchoPackets) {
  148. state = STATE.CLOSED;
  149. response = smbPacket.getTreeDisc();
  150. responsePackets.add(new Packet(response, toString()));
  151. return responsePackets;
  152. }
  153. switch (state) {
  154. case NONE:
  155. if (smbCommand == SMB_COM_NEGOTIATE) {
  156. state = STATE.CONNECTED;
  157. response = smbPacket.getNego();
  158. } else {
  159. state = STATE.DISCONNECTED;
  160. response = smbPacket.getTreeDisc();
  161. }
  162. break;
  163. case CONNECTED:
  164. if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
  165. response = smbPacket.getSessSetup();
  166. } else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
  167. state = STATE.AUTHENTICATED;
  168. response = smbPacket.getTreeCon();
  169. } else {
  170. state = STATE.DISCONNECTED;
  171. response = smbPacket.getTreeDisc();
  172. }
  173. break;
  174. case AUTHENTICATED:
  175. if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
  176. state = STATE.LISTING;
  177. response = smbPacket.getNTCreate();
  178. } else if (smbCommand == SMB_COM_ECHO) {
  179. response = smbPacket.getEcho();
  180. } else if (smbCommand == SMB_COM_TRANSACTION2) {
  181. response = smbPacket.getTrans2();
  182. } else if (smbCommand == SMB_COM_CLOSE) {
  183. response = smbPacket.getClose();
  184. } else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
  185. state = STATE.CLOSED;
  186. response = smbPacket.getTreeDisc();
  187. } else {
  188. state = STATE.DISCONNECTED;
  189. response = smbPacket.getTreeDisc();
  190. }
  191. break;
  192. case LISTING:
  193. if (smbCommand == SMB_COM_TRANSACTION) {
  194. response = smbPacket.getTrans();
  195. } else if (smbCommand == SMB_COM_CLOSE) {
  196. response = smbPacket.getClose();
  197. } else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
  198. state = STATE.CLOSED;
  199. response = smbPacket.getTreeDisc();
  200. } else if (smbCommand == SMB_COM_NEGOTIATE) {
  201. state = STATE.CONNECTED;
  202. response = smbPacket.getNego();
  203. } else {
  204. state = STATE.DISCONNECTED;
  205. response = smbPacket.getTreeDisc();
  206. }
  207. break;
  208. case DISCONNECTED:
  209. state = STATE.CLOSED;
  210. response = smbPacket.getTreeDisc();
  211. break;
  212. default:
  213. state = STATE.CLOSED;
  214. response = smbPacket.getTreeDisc();
  215. }
  216. responsePackets.add(new Packet(response, toString()));
  217. return responsePackets;
  218. }
  219. @Override
  220. public String toString() {
  221. return "SMB";
  222. }
  223. @Override
  224. public TALK_FIRST whoTalksFirst() {
  225. return TALK_FIRST.CLIENT;
  226. }
  227. }