【总结】HTML+JS逆向混淆混合

打印 上一主题 下一主题

主题 849|帖子 849|积分 2547

国外的题果然考的与众不同
[secrypt_cen.html]
这次是HTML网页,然后JS加密判断
[img=720,230.24175824175825]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328196.png[/img]
翻看JS代码
[img=720,423.74616171954966]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328197.png[/img]
很显然,关键的代码在checkPassword
[img=720,357.39130434782606]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328198.png[/img]
JS混淆是必备的
去混淆一条龙走起
先将关键代码提取出来
  1.  JavaScript
  2.  function _0x4857(_0x398c7a, _0x2b4590) { const _0x104914 =
  3.  _0x25ec(); _0x4857 = function (_0x22f014, _0x212d58) { _0x22f014 =
  4.  _0x22f014 - (0x347 + 0x46a * -0x7 + 0x1cc6); let _0x321373 =
  5.  _0x104914[_0x22f014]; return _0x321373; }; return
  6.  _0x4857(_0x398c7a, _0x2b4590); } (function (_0x414f9c, _0x3d4799)
  7.   {
  8.  //...................省略大量代码
  9.   } function safe_add(a, b) { var c = (65535 & a) + (65535 & b); return
  10.   (a >> 16) + (b >> 16) + (c >> 16) << 16 | 65535 & c } function
  11.  bit_rol(a, b) { return a << b | a >>> 32 - b }
复制代码
使用在线的javascript去混淆即可
【----帮助网安学习,以下所有学习资料免费领!加vx:dctintin,备注 “博客园” 获取!】
 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)
deobfuscate.relative.im

得到去混淆后的结果
  1.  function checkPassword(_0x38d32a) {
  2.  try {
  3.  if (_0x38d32a.length !== 21) {
  4.  return false
  5.   }
  6.  if (
  7.  //......省略大量代码
  8.  return [c, d, j, k]
  9.   }
  10.  function md5_cmn(a, b, c, d, e, f) {
  11.  return safe_add(bit_rol(safe_add(safe_add(b, a), safe_add(d, f)), e),
  12.  c)
  13.   }
  14.  function md5_ff(a, b, c, d, e, f, g) {
  15.  return md5_cmn((b & c) | (~b & d), a, b, e, f, g)
  16.   }
  17.  function md5_gg(a, b, c, d, e, f, g) {
  18.  return md5_cmn((b & d) | (c & ~d), a, b, e, f, g)
  19.   }
  20.  function md5_hh(a, b, c, d, e, f, g) {
  21.  return md5_cmn(b ^ c ^ d, a, b, e, f, g)
  22.   }
  23.  function md5_ii(a, b, c, d, e, f, g) {
  24.  return md5_cmn(c ^ (b | ~d), a, b, e, f, g)
  25.   }
  26.  function safe_add(a, b) {
  27.  var c = (65535 & a) + (65535 & b)
  28.  return (((a >> 16) + (b >> 16) + (c >> 16)) << 16) | (65535 &
  29.  c)
  30.   }
  31.  function bit_rol(a, b) {
  32.  return (a << b) | (a >>> (32 - b))
  33.   }
复制代码
[img=720,500.7221350078493]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328201.png[/img]
[img=720,403.1506849315069]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328202.png[/img]
flag长度21
[img=720,186.0287081339713]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328203.png[/img]
发现了MD5加密,和两个MD5字符串
[img=720,213.49470499243571]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328204.png[/img]


看起来无关联?
后来审计整个代码发现,对输入的flag分部分进行判断比较

写出对应的部分,在控制台console输出相关信息是一个不错的选择
[img=720,99.10931174089069]https://m-1254331109.cos.ap-guangzhou.myqcloud.com/202402061328208.png[/img]
  1.  function checkPassword(_0x38d32a) {
  2.  try {
  3.  // Password length is 21.
  4.  if (_0x38d32a.length !== 21) {
  5.  return false;
  6.   }
  7.  if (
  8.  _0x38d32a.slice(1, 2) !==
  9.   (String.fromCodePoint + "")[
  10.  parseInt((parseInt + "").charCodeAt(3), 16) - 147
  11.   ] /* password[1] = 'o' */ ||
  12.  _0x38d32a[(parseInt(41, 6) >> 2) - 2] !==
  13.  String.fromCodePoint(123) /* password[4] = '{' */ ||
  14.  _0x38d32a[4].charCodeAt(0) !==
  15.  _0x38d32a[7].charCodeAt(0) + 72 /* password[7] = '3'. */ ||
  16.  JSON.stringify(
  17.  Array.from(
  18.  _0x38d32a.slice(5, 7).split("").reverse().join(),
  19.   (_0x2d4d73) => _0x2d4d73.codePointAt(0)
  20.   ).map((_0x5b85c5) => _0x5b85c5 + 213)
  21.   ) !==
  22.  JSON.stringify([
  23.  285, 257, 297,
  24.   ]) /* password[5] = 'T', password[6] = 'H' password[7] =
  25.   '3'*/
  26.   ) {
  27.  return false;
  28.   }
  29.  /* For password[8], password[9], password[10], password[11]
  30.   */
  31.  let _0x3c7a5c = _0x38d32a.slice(8, 12).split("").reverse();
  32.  
  33.  try {
  34.  for (let _0x396662 = 0; _0x396662 < 5; _0x396662++) {
  35.  _0x3c7a5c[_0x396662] =
  36.  _0x3c7a5c[_0x396662].charCodeAt(0) + _0x396662 +
  37.  getAdder(_0x396662);
  38.   }
  39.   } catch (_0x1fbd51) {
  40.  _0x3c7a5c = _0x3c7a5c.map(
  41.   (_0x24cda7) => (_0x24cda7 += _0x1fbd51.constructor.name.length -
  42.  4)
  43.   );
  44.   }
  45.  
  46.  if (
  47.  MD5(String.fromCodePoint(..._0x3c7a5c)) !==
  48.  "098f6bcd4621d373cade4e832627b4f6" /* password[8] = '0',
  49.   password[9] = 'R', password[10] = '3', password[11] = 'M'
  50.   */
  51.   ) {
  52.  return false;
  53.   }
  54.  
  55.  if (
  56.  MD5(_0x38d32a.charCodeAt(12) + "") !==
  57.  "812b4ba287f5ee0bc9d43bbf5bbe87fb" /* password[12] = '_' */
  58.   ) {
  59.  return false;
  60.   }
  61.  _0x3c7a5c = (_0x38d32a[8] + _0x38d32a[11]).split("");
  62.  _0x3c7a5c.push(_0x3c7a5c.shift());
  63.  if (
  64.  _0x38d32a.substring(14, 16) !==
  65.  String.fromCodePoint(
  66.  ..._0x3c7a5c.map((_0x5b5ec8) =>
  67.  Number.isNaN(+_0x5b5ec8) ? _0x5b5ec8.charCodeAt(0) + 5 : 48
  68.   )
  69.   ) /* password[14] = 'R' password[15] = '0' */ ||
  70.  _0x38d32a[_0x38d32a[7] - _0x38d32a[10]] !==
  71.  atob("dQ==") /* password[0] = 'u' */ ||
  72.  _0x38d32a.indexOf(String.fromCharCode(117)) !==
  73.  _0x38d32a[7] - _0x38d32a[17] /* password[17] = '3' */ ||
  74.  JSON.stringify(
  75.  _0x38d32a
  76.   .slice(2, 4)
  77.   .split("")
  78.   .map(
  79.   (_0x7bf0a6) =>
  80.  _0x7bf0a6.charCodeAt(0) ^
  81.  getAdder.name[_0x38d32a[7]].charCodeAt(0)
  82.   )
  83.   ) !==
  84.  JSON.stringify(
  85.   [72, 90].map(
  86.   (_0x40ab0d) =>
  87.  _0x40ab0d ^
  88.  String.fromCodePoint.name[_0x38d32a[17] - 1].charCodeAt(0)
  89.   )
  90.   ) /* password[2] = 'f', password[3] = 't' */
  91.   ) {
  92.  return false;
  93.   }
  94.  if (
  95.  String.fromCodePoint(
  96.  ..._0x38d32a
  97.   .split("")
  98.   .filter(
  99.   (_0x5edfac, _0x2965d2) => _0x2965d2 > 15 && _0x2965d2 % 2 == 0
  100.   )
  101.   .map(
  102.   (_0x2ffa6d) =>
  103.  _0x2ffa6d.charCodeAt(0) ^ (_0x38d32a.length + _0x38d32a[7])
  104.   )
  105.   ) !==
  106.  atob(
  107.  "g5Go"
  108.   ) /* password[16] = 'V', password[18] = 'D', password[20] =
  109.   '}' */
  110.   ) {
  111.  return false;
  112.   }
  113.  if (
  114.  _0x38d32a[_0x38d32a.length - 2] !==
  115.  String.fromCharCode(Math.floor((({} + "").charCodeAt(0) + 9) / 3))
  116.  ||
  117.  _0x38d32a[1 + _0x38d32a[7]] !== giggity()[5] /* password[19]
  118.   = ! */
  119.   ) {
  120.  return false;
  121.   }
  122.  return true;
  123.   } catch (_0x4d4983) {
  124.  return false;
  125.   }
  126.   }
  127.  function getAdder(_0x430c9d) {
  128.  switch (_0x430c9d) {
  129.  case 0:
  130.  return 34;
  131.  case 1:
  132.  return 44;
  133.  case 2:
  134.  return 26;
  135.  case 3:
  136.  return 60;
  137.   }
  138.  return 101;
  139.   }
  140.  function giggity() {
  141.  return giggity.caller.name;
  142.   }
复制代码
得到flag
uoft{TH30R3M_PR0V3D!}
更多网安技能的在线实操练习,请点击这里>>
  

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

悠扬随风

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表