Guest User

Untitled

a guest
May 26th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.87 KB | None | 0 0
  1. ### no-js
  2.  
  3. This challenge is a usual crackme, but implemented in javascript. First step is to find entry point and what is happening with entered input.
  4. ```javascript
  5. function Tk() {
  6. var a = dj.c(""),
  7. b = dj.c(!1),
  8. c = dj.c(!1),
  9. d = dj.c(!1);
  10. return function(a, b, c, d) {
  11. return function() {
  12. return new Y(null, 5, 5, Z, [yh, new Va(null, 1, [Gh, "container"], null), new Y(null, 3, 5, Z, [yh, new Va(null, 1, [Gh, ["background ", D.c(y(I(c)) ? "background-b" : "background-a")].join("")], null), new Y(null, 2, 5, Z, [Zh, new Va(null, 1, [sh, ["images/", D.c(y(I(c)) ? "FGKG09C" : "FGKG09B"), ".jpg"].join("")], null)], null)], null), new Y(null, 4, 5, Z, [yh, new Va(null, 1, [Gh, "absolute-center"], null), Ya(function() {
  13. var a = I(c);
  14. return y(a) ?
  15. a : I(b)
  16. }()) ? new Y(null, 4, 5, Z, [bh, Kk, new Va(null, 2, [Yh, function(a, b) {
  17. return function() {
  18. return Ke(b, !0)
  19. }
  20. }(a, b, c, d), mh, !0], null), "Enter Password"], null) : null, y(I(c)) ? new Y(null, 4, 5, Z, [yh, new Va(null, 1, [xh, new Va(null, 4, [Yg, "white", Ph, "3em", Kh, "center", ah, "0px 2px 15px green"], null)], null), new Y(null, 2, 5, Z, [Vh, "Flag correct!"], null), new Y(null, 2, 5, Z, [Vh, ["RCTF{", D.c(I(a)), "}"].join("")], null)], null) : null], null), y(function() {
  21. var a = I(b);
  22. return y(a) ? Ya(I(c)) : a
  23. }()) ? new Y(null, 6, 5, Z, [bh, Mk, new Va(null, 2, [zh,
  24. "blurring", Sg, I(b)
  25. ], null), new Y(null, 3, 5, Z, [bh, Ok, "Input"], null), new Y(null, 4, 5, Z, [bh, Pk, y(I(d)) ? Ya(I(c)) ? new Y(null, 3, 5, Z, [Vh, new Va(null, 1, [xh, new Va(null, 2, [Yg, "red", Kh, "center"], null)], null), "Flag incorrect"], null) : null : null, new Y(null, 2, 5, Z, [Sk, a], null)], null), new Y(null, 3, 5, Z, [bh, Qk, new Y(null, 4, 5, Z, [bh, Kk, new Va(null, 2, [Yh, function(a, b, c, d) {
  26. return function() {
  27. y(Rk(I(a))) && Ke(c, !0);
  28. Ke(d, !0);
  29. return setTimeout(function(a, b, c, d) {
  30. return function() {
  31. return Ke(d, !1)
  32. }
  33. }(a, b, c, d), 5E3)
  34. }
  35. }(a, b, c, d), mh, !0],
  36. null), "Verify"], null)], null)], null) : null], null)
  37. }
  38. }(a, b, c, d)
  39. }
  40. ```
  41.  
  42. In this part of code "Flag is correct/incorrect" strings are exposed and expected flag format: `["RCTF{", D.c(I(a)), "}"]`. In function `Rk` we can spot our input string:
  43. ```javascript
  44. function Rk(a) {
  45. rg = gi(a, "_");
  46. // if (K.f(S(rg), S(sg))) {
  47. // return K.f(S(Se(Fd, Re(function(a) { return we(yb(a), new Y(null, 1, 5, Z, [xb(a)], null)) }, qg()))), S(sg));
  48. // }
  49. return K.f(S(rg), S(sg)) ? K.f(S(Se(Fd, Re(function(a) {
  50. return we(yb(a), new Y(null, 1, 5, Z, [xb(a)], null))
  51. }, qg()))), S(sg)) : !1
  52. }
  53. ```
  54. which is later split by underscores and object `rg` is formed from it and number of splitted parts is compared to number of elements in `sg.pa` field. Thus we can learn that flag is looking like `A_B_C_D_E_F_G`. By placing breakpoints inside of fuctions of `sg.pa` array we can find that splitted parts of input are correspondingly checked by functions from that array, so we can expect that to successfully recover the flag we need to pass all 7 checks in that object.
  55.  
  56. ### Part A
  57. ```javascript
  58. var sg = new Y(null, 7, 5, Z, [function(a) {
  59. return K.f(a, "no")
  60. }
  61. ```
  62. It is a simple check `a === "no"`, so first part of flag is "no".
  63.  
  64. ### Part B
  65. ```javascript
  66. function(a) {
  67. return K.f(0, Kd(new Y(null, 10, 5, Z, [45, 36, 57, 36, 54, 38, 53, 1, 51, 55], null), li(a)))
  68. }
  69. ```
  70. It is a check that `li(a) === [45, 36, 57, 36, 54, 38, 53, 1, 51, 55]`. `li` is a simple function mapping symbols in the following way:
  71. ```javascript
  72. function li(a) {
  73. return Re(function(a) {
  74. a = a.charCodeAt();
  75. return 57 >= a ? a - 48 : 90 >= a ? a - 65 + 10 : 122 >= a ? a - 97 + 36 : null
  76. }, a.split(""))
  77. }
  78. ```
  79. So we can recover symbols back from given array, second part of the flag is `javascr1pt`.
  80.  
  81. ### Parts C and D
  82. ```javascript
  83. function(a) {
  84. return K.f(mi(a), "0SWCRMLH")
  85. }, function(a) {
  86. return K.f(mi(a), "000EQTPI")
  87. }
  88. ```
  89. This checks are calculating some kind of hash from input string and compares it to given values. At first step seven numbers are calculated from input string, (`J.f(ki, 5 * a)` is a first element of input string, `J.f(ki, 5 * a + 1)` - second and so on):
  90. ```javascript
  91. var first = J.f(ki, 5 * a) >> 3;
  92. var second = Fc(
  93. [
  94. (J.f(ki, 5 * a) & 7) << 2 | J.f(ki, 5 * a + 1) >> 6,
  95. (J.f(ki, 5 * a + 1) & 63) >> 1,
  96. (J.f(ki, 5 * a + 1) & 1) << 4 | J.f(ki, 5 * a + 2) >> 4,
  97. (J.f(ki, 5 * a + 2) & 15) << 1 | J.f(ki, 5 * a + 3) >> 7,
  98. (J.f(ki, 5 * a + 3) & 127) >> 2,
  99. (J.f(ki, 5 * a + 3) & 3) << 3 | J.f(ki, 5 * a + 4) >> 5,
  100. J.f(ki, 5 * a + 4) & 31
  101. ]
  102. );
  103. ```
  104. At the second step those numbers are used as indicies in alphabet string "765432ABCDEFGHIJKLMNOPQRSTUVWXYZ", resulting is padded with zeroes and then reversed. Padding:
  105. ```javascript
  106. ji = K.f(c, 1) ? 6 : K.f(c, 2) ? 4 : K.f(c, 3) ? 3 : K.f(c, 4) ? 1 : 0;
  107. ```
  108. `K.f(c, 1) === (c, n) => { c.length === n }` - true if length of input string is 1. So for 3 zeroes in pad input must have length of 3 and for 1 zero length of 4. By reversing strings "0SWCRMLH" and "000EQTPI" to indices in alphabet and reversing all bitwise operations from aforementioned formulas we can learn next two parts of flag - "lets" and "use".
  109.  
  110. ### Part E
  111.  
  112. ```javascript
  113. function Bk(a) {
  114. var j=window['BigInt'],w=j['asIntN'];
  115. var first = w(256,"276839132707622690534147184366986393054208");
  116. var second = D.c(fi(",", Ak(a, Vg))).split(',');
  117. var third = second.map(j).reduce((a, b)=>a*256n+b)<<10n;
  118. return first === third;
  119. }
  120. function Ak(a) {
  121. for (var b = [], c = arguments.length, d = 0;;)
  122. if (d < c) b.push(arguments[d]), d += 1;
  123. else break;
  124. c = arguments[0];
  125. d = arguments[1];
  126. b = ld(2 < b.length ? new M(b.slice(2), 0, null) : null, 0);
  127. a: switch (d = d instanceof v ? d.Ia : null, d) {
  128. case "md5":
  129. var e = new yk;
  130. break a;
  131. default:
  132. throw Error(["No matching clause: ", D.c(d)].join(""));
  133. }
  134. d = [];
  135. for (var f = 0, g = 0; g < c.length; g++) {
  136. var k = c.charCodeAt(g);
  137. 128 > k ? d[f++] = k : (2048 > k ? d[f++] = k >> 6 | 192 : (55296 == (k & 64512) && g + 1 < c.length && 56320 == (c.charCodeAt(g + 1) & 64512) ? (k = 65536 + ((k & 1023) << 10) + (c.charCodeAt(++g) &
  138. 1023), d[f++] = k >> 18 | 240, d[f++] = k >> 12 & 63 | 128) : d[f++] = k >> 12 | 224, d[f++] = k >> 6 & 63 | 128), d[f++] = k & 63 | 128)
  139. }
  140. c = e;
  141. c.update(d);
  142. c = c.digest();
  143. return y(b) ? wk(c) : c
  144. }
  145. ```
  146. Function `Ak` calculates md5-hash from input string, which is later multiplied by 1024 and compared to some value in function `Bk`. By dividing it we can learn what is desired value of md5: cb63a762f1571806222efef7ec7f9c1b and then google this value. Next part of flag is "50me".
  147.  
  148. ### Part F
  149. At first step input characters are split by pairs and converted into objects:
  150. ```javascript
  151. oi = ti(He.f(vg(function(a) {
  152. return ze(a, 12)
  153. }), ug()));
  154. Re(function(a) {
  155. return Sd(oi, a)
  156. }, li(a));
  157. ```
  158. At second step some function from these objects will be compared to predefined values:
  159. ```javascript
  160. return K.f(Kd(new Y(null, 6, 5, Z, [21104, 50328, 78128, 119488, 411168, 592832], null), function() {
  161. ```
  162. By placing breakpoint inside `Kd` function we can learn what are values that being compared, if we pass string "111111111111" as input: `[514, 1028, 2056, 4112, 8224, 16448, 32896]`. Using that internal formula can be guessed: `(li(first) * 512 + li(second)) * 2 ** (index)`, by computing values backwards for given numbers next part of flag is recovered: "funcccTional".
  163.  
  164. ### Part G
  165.  
  166. Last part of the flag is checked by comparing some function of input value with given base64-encoded string `"PVw6U2ZmYV1hRVAyUS9IW1t..."`. By passing different input string we can learn that each symbol of input string produces 11 symbols in output string and those symbols are "predefined". Resulting symbols are produced with the following code:
  167. ```javascript
  168. ed(c + g, w(Hc(a)))
  169. ```
  170. each symbol in input is summed with 11 symbols in linked list which is produced by
  171. ```javascript
  172. xe(hd, xe(hd, be(22, 33), li("okotta")), new Y(null, 3, 5, Z, [11, 45, 14], null))
  173. ```
  174. First value in that list is 14, so we can subtract 14 from first symbol in each block of 11 symbols in base64 decoded string `"PVw6U2ZmYV1hRVAyUS9IW1t..."` and recover last part of the flag: "laaaannGuageeee1".
  175.  
  176. ### Flag
  177.  
  178. RCTF{no_javascr1pt_lets_use_50me_funcccTional_laaaannGuageeee1}
Add Comment
Please, Sign In to add comment