SMB.java 6.2 KB

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