SMB.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. package de.tudarmstadt.informatik.hostage.protocol;
  2. import java.nio.ByteBuffer;
  3. import java.util.ArrayList;
  4. import java.util.Calendar;
  5. import java.util.List;
  6. import java.util.Random;
  7. import java.util.TimeZone;
  8. public final class SMB implements Protocol {
  9. private static enum STATE {
  10. NONE, CONNECTED, AUTHENTICATED, LISTING, DISCONNECTED, CLOSED
  11. }
  12. private STATE state = STATE.NONE;
  13. @Override
  14. public int getPort() {
  15. return 8445;
  16. }
  17. @Override
  18. public TALK_FIRST whoTalksFirst() {
  19. return TALK_FIRST.CLIENT;
  20. }
  21. @Override
  22. public List<byte[]> processMessage(byte[] message) {
  23. SmbPacket packet = new SmbPacket(message);
  24. byte smbCommand = packet.getSmbCommand();
  25. List<byte[]> response = new ArrayList<byte[]>();
  26. switch (state) {
  27. case NONE:
  28. if (smbCommand == 0x72) {
  29. state = STATE.CONNECTED;
  30. response.add(packet.getNego());
  31. } else {
  32. state = STATE.DISCONNECTED;
  33. response.add(packet.getTreeDisc());
  34. }
  35. break;
  36. case CONNECTED:
  37. if (smbCommand == 0x73) {
  38. response.add(packet.getSessSetup());
  39. } else if (smbCommand == 0x75) {
  40. state = STATE.AUTHENTICATED;
  41. response.add(packet.getTreeCon());
  42. } else {
  43. state = STATE.DISCONNECTED;
  44. response.add(packet.getTreeDisc());
  45. }
  46. break;
  47. case AUTHENTICATED:
  48. if (smbCommand == (byte) 0xa2) {
  49. state = STATE.LISTING;
  50. response.add(packet.getNTCreate());
  51. } else if (smbCommand == 0x2b) {
  52. response.add(packet.getEcho());
  53. } else if (smbCommand == 0x32) {
  54. response.add(packet.getTrans2());
  55. } else if (smbCommand == 0x04) {
  56. response.add(packet.getClose());
  57. } else if (smbCommand == 0x71) {
  58. state = STATE.CLOSED;
  59. response.add(packet.getTreeDisc());
  60. } else {
  61. state = STATE.DISCONNECTED;
  62. response.add(packet.getTreeDisc());
  63. }
  64. break;
  65. case LISTING:
  66. if (smbCommand == 0x25) {
  67. response.add(packet.getTrans());
  68. } else if (smbCommand == 0x04) {
  69. response.add(packet.getClose());
  70. } else if (smbCommand == 0x71) {
  71. state = STATE.CLOSED;
  72. response.add(packet.getTreeDisc());
  73. } else if (smbCommand == 0x72) {
  74. state = STATE.CONNECTED;
  75. response.add(packet.getNego());
  76. } else {
  77. state = STATE.DISCONNECTED;
  78. response.add(packet.getTreeDisc());
  79. }
  80. break;
  81. case DISCONNECTED:
  82. state = STATE.CLOSED;
  83. response.add(packet.getTreeDisc());
  84. break;
  85. default:
  86. state = STATE.CLOSED;
  87. response.add(packet.getTreeDisc());
  88. }
  89. return response;
  90. }
  91. @Override
  92. public boolean isClosed() {
  93. return (state == STATE.CLOSED);
  94. }
  95. @Override
  96. public String toString() {
  97. return "SMB";
  98. }
  99. public byte[] concat(byte[]... bytes) {
  100. int newSize = 0;
  101. for (byte[] b : bytes)
  102. newSize += b.length;
  103. byte[] dst = new byte[newSize];
  104. int currentPos = 0;
  105. int newPos;
  106. for (byte[] b : bytes) {
  107. newPos = b.length;
  108. System.arraycopy(b, 0, dst, currentPos, newPos);
  109. currentPos += newPos;
  110. }
  111. return dst;
  112. }
  113. public byte[] getTimeInBytes() {
  114. long time = System.currentTimeMillis();
  115. Calendar calend = Calendar.getInstance();
  116. calend.setTimeZone(TimeZone.getTimeZone("UTC"));
  117. calend.set(1601, 0, 01, 00, 00, 00);
  118. time -= calend.getTimeInMillis();
  119. time *= 10000;
  120. byte[] b = new byte[8];
  121. byte[] b2 = ByteBuffer.allocate(8).putLong(time).array();
  122. for (int i = 0, j = 7; i < 8 && j > -1; i++, j--) {
  123. b[i] = (byte) (b2[j] & 0xff);
  124. }
  125. return b;
  126. }
  127. public byte[] randomBytes(int size) {
  128. byte[] bytes = new byte[size];
  129. Random rdm = new Random();
  130. rdm.nextBytes(bytes);
  131. return bytes;
  132. }
  133. public String charToString(char[] chars) {
  134. char[] newChars = new char[chars.length];
  135. for (int i = 0, j = 0; i < chars.length && j < newChars.length; i++) {
  136. if (isLetter(chars[i])) {
  137. newChars[j] = chars[i];
  138. j++;
  139. }
  140. }
  141. return new String(newChars);
  142. }
  143. public byte[] charToByte(char[] chars) {
  144. byte[] bytes = new byte[chars.length];
  145. for (int i = 0; i < chars.length; i++)
  146. bytes[i] = (byte) chars[i];
  147. return bytes;
  148. }
  149. public char[] byteToChar(byte[] bytes) {
  150. char[] chars = new char[bytes.length];
  151. for (int i = 0; i < bytes.length; i++)
  152. chars[i] = (char) bytes[i];
  153. return chars;
  154. }
  155. private boolean isLetter(char c) {
  156. return (c >= 32 && c <= 127);
  157. }
  158. private class SmbPacket {
  159. private byte[] msg = null;
  160. private final byte[] serverGUID = randomBytes(16);
  161. private boolean authenticateNext = false;
  162. private byte[] serverComp = new byte[4];
  163. private byte[] smbCommand = new byte[1];
  164. private byte[] ntStat = new byte[4];
  165. private byte[] smbFlags = new byte[1];
  166. private byte[] smbFlags2 = new byte[2];
  167. private byte[] processIDHigh = new byte[2];
  168. private byte[] signature = new byte[8];
  169. private byte[] reserved = new byte[2];
  170. private byte[] treeID = new byte[2];
  171. private byte[] processID = new byte[2];
  172. private byte[] userID = new byte[2];
  173. private byte[] multiplexID = new byte[2];
  174. public SmbPacket(byte[] message) {
  175. this.msg = message;
  176. serverComp = new byte[] { message[4], message[5], message[6],
  177. message[7] };
  178. smbCommand = new byte[] { message[8] };
  179. ntStat = new byte[] { message[9], message[10], message[11],
  180. message[12] };
  181. smbFlags = new byte[] { (byte) (message[13] | 0x80) }; // | 0x80 for
  182. // mark
  183. // response
  184. // bit
  185. smbFlags2 = new byte[] { message[14], message[15] };
  186. processIDHigh = new byte[] { message[16], message[17] };
  187. signature = new byte[] { message[18], message[19], message[20],
  188. message[21], message[22], message[23], message[24],
  189. message[25] };
  190. reserved = new byte[] { message[26], message[27] };
  191. treeID = new byte[] { message[28], message[29] };
  192. processID = new byte[] { message[30], message[31] };
  193. userID = new byte[] { message[32], message[33] };
  194. multiplexID = new byte[] { message[34], message[35] };
  195. }
  196. private byte[] getNetbios(byte[] response) {
  197. byte[] netbios = { 0x00 };
  198. byte[] buf = ByteBuffer.allocate(4).putInt(response.length).array(); // allocate(4)
  199. // because
  200. // int
  201. // is
  202. // 4
  203. // bytes
  204. // long
  205. byte[] netbiosLength = { buf[1], buf[2], buf[3] }; // only bytes 1-3
  206. // needed, byte
  207. // 0 is not
  208. // needed
  209. return concat(netbios, netbiosLength);
  210. }
  211. private byte[] getHeader() {
  212. byte[] header = new byte[0];
  213. return concat(header, serverComp, smbCommand, ntStat, smbFlags,
  214. smbFlags2, processIDHigh, signature, reserved, treeID,
  215. processID, userID, multiplexID);
  216. }
  217. public byte[] getNego() {
  218. byte[] wordCount = { 0x11 };
  219. byte[] dialect = evaluateDialect();
  220. byte[] secMode = { 0x03 };
  221. byte[] maxMpxC = { 0x32, 0x00 };
  222. byte[] maxVcs = { 0x01, 0x00 };
  223. byte[] maxBufSize = { 0x04, 0x11, 0x00, 0x00 };
  224. byte[] maxRawBuf = { 0x00, 0x00, 0x01, 0x00 };
  225. byte[] sessionKey = { 0x00, 0x00, 0x00, 0x00 };
  226. byte[] capabilities = { (byte) 0xfc, (byte) 0xe3, 0x01, (byte) 0x80 };
  227. byte[] sysTime = getTimeInBytes();
  228. byte[] timeZone = { (byte) 0x88, (byte) 0xff }; // FIXME correct
  229. // time zone
  230. byte[] keyLength = { 0x00 };
  231. byte[] byteCount = { 0x3a, 0x00 };
  232. byte[] guid = serverGUID;
  233. byte[] secBlob = { 0x60, 0x28, 0x06, 0x06 };
  234. byte[] oid = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 };
  235. byte[] protectNeg = { (byte) 0xa0, 0x1e };
  236. byte[] negToken = { 0x30, 0x1c, (byte) 0xa0, 0x1a, 0x30, 0x18 };
  237. byte[] mechType = { 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
  238. (byte) 0x82, 0x37, 0x02, 0x02, 0x1e };
  239. byte[] mechType2 = { 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
  240. (byte) 0x82, 0x37, 0x02, 0x02, 0x0a };
  241. byte[] response = concat(getHeader(), wordCount, dialect, secMode,
  242. maxMpxC, maxVcs, maxBufSize, maxRawBuf, sessionKey,
  243. capabilities, sysTime, timeZone, keyLength, byteCount,
  244. guid, secBlob, oid, protectNeg, negToken, mechType,
  245. mechType2);
  246. return concat(getNetbios(response), response);
  247. }
  248. private byte[] evaluateDialect() {
  249. byte[] dialectMsg = java.util.Arrays.copyOfRange(msg, 39,
  250. msg.length);
  251. short dialectNumber = 0;
  252. for (int i = 0, start = 0; i < dialectMsg.length; i++) {
  253. if (dialectMsg[i] == 0x00) {
  254. if (new String(java.util.Arrays.copyOfRange(dialectMsg,
  255. start, i)).contains("NT LM 0.12")) {
  256. return new byte[] { (byte) dialectNumber,
  257. (byte) (dialectNumber >> 8) };
  258. }
  259. start = i + 1;
  260. dialectNumber++;
  261. }
  262. }
  263. return new byte[] { 0x00, 0x00 };
  264. }
  265. public byte[] getSessSetup() {
  266. if (authenticateNext)
  267. return getSetupAuth();
  268. else {
  269. authenticateNext = true;
  270. return getSetupChal();
  271. }
  272. }
  273. private byte[] getSetupChal() {
  274. byte[] wordCount = { 0x04 };
  275. byte[] andXCommand = { (byte) 0xff };
  276. byte[] reserved = { 0x00 };
  277. byte[] andXOffset = { 0x60, 0x01 };
  278. byte[] action = { 0x00, 0x00 };
  279. byte[] secBlobLength = { (byte) 0xc7, 0x00 };
  280. byte[] byteCount = { 0x35, 0x01 };
  281. byte[] secBlob = { (byte) 0xa1, (byte) 0x81, (byte) 0xc4 };
  282. byte[] negToken = { 0x30, (byte) 0x81, (byte) 0xc1, (byte) 0xa0,
  283. 0x03, 0x0a, 0x01 };
  284. byte[] negResult = { 0x01 };
  285. byte[] negToken2 = { (byte) 0xa1, 0x0c, 0x06, 0x0a };
  286. byte[] supportedMech = { 0x2b, 0x06, 0x01, 0x04, 0x01, (byte) 0x82,
  287. 0x37, 0x02, 0x02, 0x0a };
  288. byte[] negToken3 = { (byte) 0xa2, (byte) 0x81, (byte) 0xab, 0x04,
  289. (byte) 0x81, (byte) 0xa8 };
  290. byte[] respToken = { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50,
  291. 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x38,
  292. 0x00, 0x00, 0x00, 0x15, (byte) 0x82, (byte) 0x8a, 0x62 };
  293. byte[] challenge = randomBytes(8);
  294. byte[] respToken2 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  295. 0x00, 0x60, 0x00, 0x60, 0x00, 0x48, 0x00, 0x00, 0x00, 0x06,
  296. 0x01, (byte) 0xb0, 0x1d, 0x00, 0x00, 0x00, 0x0f, 0x42,
  297. 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45,
  298. 0x00, 0x53, 0x00, 0x53, 0x00, 0x02, 0x00, 0x10, 0x00, 0x42,
  299. 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45,
  300. 0x00, 0x53, 0x00, 0x53, 0x00, 0x01, 0x00, 0x10, 0x00, 0x42,
  301. 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45,
  302. 0x00, 0x53, 0x00, 0x53, 0x00, 0x04, 0x00, 0x10, 0x00, 0x42,
  303. 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45,
  304. 0x00, 0x53, 0x00, 0x53, 0x00, 0x03, 0x00, 0x10, 0x00, 0x42,
  305. 0x00, 0x55, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x45,
  306. 0x00, 0x53, 0x00, 0x53, 0x00, 0x07, 0x00, 0x08, 0x00 };
  307. byte[] timeStamp = getTimeInBytes();
  308. byte[] respToken3 = { 0x00, 0x00, 0x00, 0x00 };
  309. byte[] nativOS = { 0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00,
  310. 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37, 0x00,
  311. 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00,
  312. 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
  313. 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x37, 0x00,
  314. 0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00 }; // Windows
  315. // 7
  316. // Professional
  317. // 7600
  318. byte[] nativLanMngr = { 0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64,
  319. 0x00, 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37,
  320. 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66,
  321. 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f,
  322. 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x36,
  323. 0x00, 0x2e, 0x00, 0x31, 0x00, 0x00, 0x00 }; // Windows 7
  324. // Professional
  325. // 6.1
  326. ntStat = new byte[] { 0x16, 0x00, 0x00, (byte) 0xc0 };
  327. userID = new byte[] { 0x00, 0x08 };
  328. byte[] response = concat(getHeader(), wordCount, andXCommand,
  329. reserved, andXOffset, action, secBlobLength, byteCount,
  330. secBlob, negToken, negResult, negToken2, supportedMech,
  331. negToken3, respToken, challenge, respToken2, timeStamp,
  332. respToken3, nativOS, nativLanMngr);
  333. return concat(getNetbios(response), response);
  334. }
  335. private byte[] getSetupAuth() {
  336. byte[] wordCount = { 0x04 };
  337. byte[] andXCommand = { (byte) 0xff };
  338. byte[] reserved = { 0x00 };
  339. byte[] andXOffset = { (byte) 0xa2, 0x00 };
  340. byte[] action = { 0x01, 0x00 };
  341. byte[] secBlobLength = { 0x09, 0x00 };
  342. byte[] byteCount = { (byte) 0x77, 0x00 };
  343. byte[] secBlob = { (byte) 0xa1, 0x07, 0x30, 0x05, (byte) 0xa0,
  344. 0x03, 0x0a, 0x01, 0x00 };
  345. byte[] nativOS = { 0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00,
  346. 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37, 0x00,
  347. 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66, 0x00,
  348. 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00,
  349. 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x37, 0x00,
  350. 0x36, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00 }; // Windows
  351. // 7
  352. // Professional
  353. // 7600
  354. byte[] nativLanMngr = { 0x57, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64,
  355. 0x00, 0x6f, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x37,
  356. 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x66,
  357. 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f,
  358. 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x36,
  359. 0x00, 0x2e, 0x00, 0x31, 0x00, 0x00, 0x00 }; // Windows 7
  360. // Professional
  361. // 6.1
  362. byte[] response = concat(getHeader(), wordCount, andXCommand,
  363. reserved, andXOffset, action, secBlobLength, byteCount,
  364. secBlob, nativOS, nativLanMngr);
  365. return concat(getNetbios(response), response);
  366. }
  367. public byte[] getTreeCon() {
  368. String str = toString();
  369. byte[] wordCount = { 0x00 };
  370. byte[] andXCommand = { 0x00, 0x00 };
  371. byte[] response = null;
  372. if (str.contains("IPC$") || str.contains("DOCS")) {
  373. wordCount = new byte[] { 0x07 };
  374. andXCommand = new byte[] { (byte) 0xff };
  375. byte[] reserved = { 0x00 };
  376. byte[] andXOffset = { 0x38, 0x00 };
  377. byte[] optionalSupport = { 0x01, 0x00 };
  378. byte[] maxShareAccess = { (byte) 0xff, (byte) 0xff, 0x1f, 0x00 };
  379. byte[] guestMaxShareAccess = { (byte) 0xff, (byte) 0xff, 0x1f,
  380. 0x00 };
  381. byte[] byteCount = { 0x07, 0x00 };
  382. byte[] service = { 0x49, 0x50, 0x43, 0x00 };
  383. byte[] extraParameters = { 0x00, 0x00, 0x00 };
  384. treeID = new byte[] { 0x00, 0x08 };
  385. response = concat(getHeader(), wordCount, andXCommand,
  386. reserved, andXOffset, optionalSupport, maxShareAccess,
  387. guestMaxShareAccess, byteCount, service,
  388. extraParameters);
  389. } else if (str.contains("C$") || str.contains("ADMIN$")) {
  390. ntStat = new byte[] { 0x22, 0x00, 0x00, (byte) 0xc0 };
  391. response = concat(getHeader(), wordCount, andXCommand);
  392. } else {
  393. ntStat = new byte[] { (byte) 0xcc, 0x00, 0x00, (byte) 0xc0 };
  394. response = concat(getHeader(), wordCount, andXCommand);
  395. }
  396. return concat(getNetbios(response), response);
  397. }
  398. public byte[] getNTCreate() {
  399. byte[] wordCount = { 0x22 };
  400. byte[] andXCommand = { (byte) 0xff };
  401. byte[] reserved = { 0x00 };
  402. byte[] andXOffset = { 0x67, 0x00 };
  403. byte[] oplockLevel = { 0x00 };
  404. byte[] fid = { (byte) 0x00, 0x40 };
  405. byte[] createAction = { 0x01, 0x00, 0x00, 0x00 };
  406. byte[] created = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  407. byte[] lastAccess = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  408. 0x00 };
  409. byte[] lastWrite = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  410. byte[] change = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  411. byte[] fileAttributes = { (byte) 0x80, 0x00, 0x00, 0x00 };
  412. byte[] allocationSize = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
  413. 0x00 };
  414. byte[] endOfFile = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  415. byte[] fileType = { 0x02, 0x00 };
  416. byte[] ipcState = { (byte) 0xff, 0x05 };
  417. byte[] isDirectory = { 0x00 };
  418. byte[] byteCount = { 0x00, 0x00 };
  419. byte[] response = concat(getHeader(), wordCount, andXCommand,
  420. reserved, andXOffset, oplockLevel, fid, createAction,
  421. created, lastAccess, lastWrite, change, fileAttributes,
  422. allocationSize, endOfFile, fileType, ipcState, isDirectory,
  423. byteCount);
  424. return concat(getNetbios(response), response);
  425. }
  426. public byte[] getTrans() {
  427. byte[] transSub = getTransSub();
  428. byte[] response = null;
  429. if (transSub[0] == 0x00 && transSub[1] == 0x0b) {
  430. byte[] wordCount = { 0x0a };
  431. byte[] totalParamCount = { 0x00, 0x00 };
  432. byte[] totalDataCount = { 0x44, 0x00 };
  433. byte[] reserved = { 0x00, 0x00 };
  434. byte[] paramCount = { 0x00, 0x00 };
  435. byte[] paramOffset = { 0x38, 0x00 };
  436. byte[] paramDisplace = { 0x00, 0x00 };
  437. byte[] dataCount = { 0x44, 0x00 };
  438. byte[] dataOffset = { 0x38, 0x00 };
  439. byte[] dataDisplace = { 0x00, 0x00 };
  440. byte[] setupCount = { 0x00 };
  441. byte[] reserved2 = { 0x00 };
  442. byte[] byteCount = { 0x45, 0x00 };
  443. byte[] padding = { 0x00 };
  444. byte[] dcerpc = { 0x05, 0x00, 0x0c, 0x03, 0x10, 0x00, 0x00,
  445. 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  446. (byte) 0xb8, 0x10, (byte) 0xb8, 0x10, 0x4a, 0x41, 0x00,
  447. 0x00, 0x0d, 0x00, 0x5c, 0x50, 0x49, 0x50, 0x45, 0x5c,
  448. 0x73, 0x72, 0x76, 0x73, 0x76, 0x63, 0x00, 0x00, 0x01,
  449. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5d,
  450. (byte) 0x88, (byte) 0x8a, (byte) 0xeb, 0x1c,
  451. (byte) 0xc9, 0x11, (byte) 0x9f, (byte) 0xe8, 0x08,
  452. 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 };
  453. response = concat(getHeader(), wordCount, totalParamCount,
  454. totalDataCount, reserved, paramCount, paramOffset,
  455. paramDisplace, dataCount, dataOffset, dataDisplace,
  456. setupCount, reserved2, byteCount, padding, dcerpc);
  457. } else if (transSub[0] == 0x00 && transSub[1] == 0x00) {
  458. byte[] wordCount = { 0x0a };
  459. byte[] totalParamCount = { 0x00, 0x00 };
  460. byte[] totalDataCount = { 0x54, 0x01 };
  461. byte[] reserved = { 0x00, 0x00 };
  462. byte[] paramCount = { 0x00, 0x00 };
  463. byte[] paramOffset = { 0x38, 0x00 };
  464. byte[] paramDisplace = { 0x00, 0x00 };
  465. byte[] dataCount = { 0x54, 0x01 };
  466. byte[] dataOffset = { 0x38, 0x00 };
  467. byte[] dataDisplace = { 0x00, 0x00 };
  468. byte[] setupCount = { 0x00 };
  469. byte[] reserved2 = { 0x00 };
  470. byte[] byteCount = { 0x55, 0x01 };
  471. byte[] padding = { 0x00 };
  472. byte[] dcerpc = { 0x05, 0x00, 0x02, 0x03, 0x10, 0x00, 0x00,
  473. 0x00, 0x54, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  474. 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  475. byte[] serverService = { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
  476. 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00,
  477. 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00,
  478. 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, (byte) 0x80,
  479. 0x0c, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00,
  480. 0x00, 0x00, (byte) 0x80, 0x14, 0x00, 0x02, 0x00, 0x18,
  481. 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
  482. 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00,
  483. (byte) 0x80, 0x24, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00,
  484. 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
  485. 0x41, 0x00, 0x44, 0x00, 0x4d, 0x00, 0x49, 0x00, 0x4e,
  486. 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
  487. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
  488. 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x6f, 0x00,
  489. 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x41, 0x00, 0x64,
  490. 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x00, 0x00,
  491. 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  492. 0x00, 0x03, 0x00, 0x00, 0x00, 0x43, 0x00, 0x24, 0x00,
  493. 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
  494. 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x00,
  495. 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6c,
  496. 0x00, 0x74, 0x00, 0x20, 0x00, 0x73, 0x00, 0x68, 0x00,
  497. 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x00, 0x00, 0x05,
  498. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
  499. 0x00, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x73,
  500. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  501. 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
  502. 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
  503. 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x49, 0x00, 0x50,
  504. 0x00, 0x43, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
  505. 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
  506. 0x00, 0x00, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6d, 0x00,
  507. 0x6f, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x49,
  508. 0x00, 0x50, 0x00, 0x43, 0x00, 0x00, 0x00 };
  509. byte[] totalEntries = { 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 };
  510. byte[] referentID = { 0x28, 0x00, 0x02, 0x00 };
  511. byte[] resumeHandle = { 0x00, 0x00, 0x00, 0x00 };
  512. byte[] windowsError = { 0x00, 0x00, 0x00, 0x00 };
  513. response = concat(getHeader(), wordCount, totalParamCount,
  514. totalDataCount, reserved, paramCount, paramOffset,
  515. paramDisplace, dataCount, dataOffset, dataDisplace,
  516. setupCount, reserved2, byteCount, padding, dcerpc,
  517. serverService, totalEntries, referentID, resumeHandle,
  518. windowsError);
  519. }
  520. return concat(getNetbios(response), response);
  521. }
  522. public byte[] getClose() {
  523. byte[] wordCount = { 0x00 };
  524. byte[] byteCount = { 0x00, 0x00 };
  525. smbCommand = new byte[] { 0x04 };
  526. byte[] response = concat(getHeader(), wordCount, byteCount);
  527. return concat(getNetbios(response), response);
  528. }
  529. public byte[] getTreeDisc() {
  530. byte[] wordCount = { 0x00 };
  531. byte[] byteCount = { 0x00, 0x00 };
  532. smbCommand[0] = 0x71;
  533. byte[] response = concat(getHeader(), wordCount, byteCount);
  534. return concat(getNetbios(response), response);
  535. }
  536. public byte[] getEcho() {
  537. byte[] wordCount = { 0x01 };
  538. byte[] echoSeq = { 0x01, 0x00 };
  539. byte[] byteCount = { 0x10, 0x00 };
  540. byte[] echoData = { (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
  541. (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
  542. (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
  543. (byte) 0xf0, (byte) 0xf0, (byte) 0xf0, (byte) 0xf0,
  544. (byte) 0xf0 };
  545. byte[] response = concat(getHeader(), wordCount, echoSeq,
  546. byteCount, echoData);
  547. return concat(getNetbios(response), response);
  548. }
  549. public byte[] getTrans2() {
  550. byte[] response = null;
  551. byte[] wordCount = { 0x00 };
  552. byte[] andXCommand = { 0x00, 0x00 };
  553. ntStat = new byte[] { 0x22, 0x00, 0x00, (byte) 0xc0 };
  554. response = concat(getHeader(), wordCount, andXCommand);
  555. return concat(getNetbios(response), response);
  556. }
  557. private byte[] getTransSub() {
  558. byte[] transSub = new byte[2];
  559. if (smbCommand[0] == 0x32)
  560. transSub = new byte[] { msg[66], msg[65] };
  561. else if (smbCommand[0] == 0x25)
  562. transSub = new byte[] { 0x00, msg[90] };
  563. else
  564. transSub = new byte[] { 0x00, 0x00 };
  565. return transSub;
  566. }
  567. public String toString() {
  568. return new String(msg);
  569. }
  570. public byte getSmbCommand() {
  571. return smbCommand[0];
  572. }
  573. }
  574. }