SMB.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 = prefs.getInt("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. smbPacket.prepareNextResponse(NBDSType.LOCAL_MASTER_ANNOUNCEMENT_ALL);
  137. }
  138. byte smbCommand = smbPacket.getSmbCommand();
  139. byte[] response;
  140. List<Packet> responsePackets = new ArrayList<Packet>();
  141. if (smbCommand == SMB_COM_ECHO) {
  142. receivedEchoPackets++;
  143. } else {
  144. receivedEchoPackets = 0;
  145. }
  146. if (receivedEchoPackets == maxEchoPackets) {
  147. state = STATE.CLOSED;
  148. response = smbPacket.getTreeDisc();
  149. responsePackets.add(new Packet(response, toString()));
  150. return responsePackets;
  151. }
  152. switch (state) {
  153. case NONE:
  154. if (smbCommand == SMB_COM_NEGOTIATE) {
  155. state = STATE.CONNECTED;
  156. response = smbPacket.getNego();
  157. } else {
  158. state = STATE.DISCONNECTED;
  159. response = smbPacket.getTreeDisc();
  160. }
  161. break;
  162. case CONNECTED:
  163. if (smbCommand == SMB_COM_SESSION_SETUP_ANDX) {
  164. response = smbPacket.getSessSetup();
  165. } else if (smbCommand == SMB_COM_TREE_CONNECT_ANDX) {
  166. state = STATE.AUTHENTICATED;
  167. response = smbPacket.getTreeCon();
  168. } else {
  169. state = STATE.DISCONNECTED;
  170. response = smbPacket.getTreeDisc();
  171. }
  172. break;
  173. case AUTHENTICATED:
  174. if (smbCommand == SMB_COM_NT_CREATE_ANDX) {
  175. state = STATE.LISTING;
  176. response = smbPacket.getNTCreate();
  177. } else if (smbCommand == SMB_COM_ECHO) {
  178. response = smbPacket.getEcho();
  179. } else if (smbCommand == SMB_COM_TRANSACTION2) {
  180. response = smbPacket.getTrans2();
  181. } else if (smbCommand == SMB_COM_CLOSE) {
  182. response = smbPacket.getClose();
  183. } else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
  184. state = STATE.CLOSED;
  185. response = smbPacket.getTreeDisc();
  186. } else {
  187. state = STATE.DISCONNECTED;
  188. response = smbPacket.getTreeDisc();
  189. }
  190. break;
  191. case LISTING:
  192. if (smbCommand == SMB_COM_TRANSACTION) {
  193. response = smbPacket.getTrans();
  194. } else if (smbCommand == SMB_COM_CLOSE) {
  195. response = smbPacket.getClose();
  196. } else if (smbCommand == SMB_COM_TREE_DISCONNECT) {
  197. state = STATE.CLOSED;
  198. response = smbPacket.getTreeDisc();
  199. } else if (smbCommand == SMB_COM_NEGOTIATE) {
  200. state = STATE.CONNECTED;
  201. response = smbPacket.getNego();
  202. } else {
  203. state = STATE.DISCONNECTED;
  204. response = smbPacket.getTreeDisc();
  205. }
  206. break;
  207. case DISCONNECTED:
  208. state = STATE.CLOSED;
  209. response = smbPacket.getTreeDisc();
  210. break;
  211. default:
  212. state = STATE.CLOSED;
  213. response = smbPacket.getTreeDisc();
  214. }
  215. responsePackets.add(new Packet(response, toString()));
  216. return responsePackets;
  217. }
  218. @Override
  219. public String toString() {
  220. return "SMB";
  221. }
  222. @Override
  223. public TALK_FIRST whoTalksFirst() {
  224. return TALK_FIRST.CLIENT;
  225. }
  226. }