SMB.java 7.0 KB

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