Reverse Engineering
When dealing with Webpack JavaScript source code, I think I need to follow these steps:
- Run
js-beautify
for beautifying the code. - If there is code snippet that has
"use strict"
, then it should be a module. Try to write a script to extract the modules. Additionally, write a script for asking LLM about which module is custom code (non-library code). - Comment out the code snippet that is library-related or Webpack-related.
For example, when dissecting the JavaScript source code of MyOPSWAT, there are two valuable sections that contain modules. The first one is the __webpack_modules__
variable:
Inside this, the modules are clearly standout with the numeric keys.
The second one is the last self-invoking function:
Inside this function, there are custom code mixed with library code.
When Tokens and Cookies Are Set
There are some arrays like this in the last self-invoking function:
const l = [{
path: "/",
component: (0, Ze.jsx)(Qc, {}),
index: true
}, {
path: se,
component: a ? (0, Ze.jsx)(wu, {}) : (0, Ze.jsx)(Qc, {})
}, {
path: le,
component: (0, Ze.jsx)(Bg, {})
}, {
path: ce,
component: (0, Ze.jsx)(wv, {})
}, {
path: ue,
component: (0, Ze.jsx)(We, {})
}, {
path: de,
component: (0, Ze.jsx)(Ge, {})
}, {
path: pe,
component: (0, Ze.jsx)(bv, {})
}, {
path: fe,
component: (0, Ze.jsx)(ade, {})
}, {
path: "/changePassword"
}, {
path: he,
component: (0, Ze.jsx)(Ue, {})
}, {
path: "/auth-successfully",
component: (0, Ze.jsx)(Sv, {})
}];
It looks like an array for routing the paths to associated components.
When searching for URLSearchParams
, I found the following function:
function Sv() {
const e = (0, z.s0)();
const t = (0, z.TH)();
const n = new URLSearchParams(t.search);
(0, i.useEffect)(() => {
(0, Re.f3)({
accessToken: n.get("token"),
refreshToken: n.get("refresh"),
csrfToken: n.get("csrf"),
ocmToken: n.get("ocm")
}, "localstorage", "VkhWaGJqRXlNelExTmpjNA==").then(() => {
e(ae);
});
}, [n]);
return (0, Ze.jsx)(z.j3, {});
}
As we can see, this function is used for the "/auth-successfully"
route.
The Re
variable is a module:
var Re = __webpack_require__(26861);
Because we did extract the modules so we can search for the 26861.js
file. The t3
function return a function that will eventually return another function:
t.f3 = function (e, t, n) {
return ze(undefined, undefined, undefined, function () {
var r;
var o;
var i;
var a;
var s;
return Be(this, function (l) {
switch (l.label) {
case 0:
if (e) {
return [4, Xa(e == null ? undefined : e.accessToken) * 1000];
} else {
return [2, false];
}
case 1:
r = l.sent();
return [4, new Date().getTime()];
case 2:
o = l.sent();
i = o + r;
return [4, Fe((e == null ? undefined : e.ocmToken) || "", n || "")];
// ...
As we can see, the final returned function do something with the tokens.
There are some cases that use the constants such as TOKEN_KEY
, OCM_TOKEN_KEY
, etc:
case 5:
return [4, ui(Ii.TOKEN_KEY, e == null ? undefined : e.accessToken)];
case 6:
l.sent();
l.label = 7;
case 7:
return [4, ui(Ii.OCM_TOKEN_KEY, a)];
case 8:
l.sent();
return [4, ui(Ii.REFRESH_TOKEN_KEY, e == null ? undefined : e.refreshToken)];
case 9:
l.sent();
return [4, ui(Ii.CSRF_TOKEN_KEY, e == null ? undefined : e.csrfToken)];
case 10:
l.sent();
return [4, ui(Ii.TOKEN_EXPIRED_TIME, `${r}`)];
case 11:
l.sent();
return [4, li(Ii.IDAAS_SESSION_KEY, Gn(e == null ? undefined : e.ssoMeta, Ii.IDAAS_SESSION_KEY), s)];
case 12:
l.sent();
return [4, li(Ii.IDAAS_REFRESH_KEY, Gn(e == null ? undefined : e.ssoMeta, Ii.IDAAS_REFRESH_KEY), s)];
case 13:
l.sent();
return [4, li(Ii.IDAAS_PAYLOAD_KEY, Gn(e == null ? undefined : e.ssoMeta, Ii.IDAAS_PAYLOAD_KEY), s)];
case 14:
l.sent();
return [4, li(Ii.IDAAS_LOGIN_KEY, Gn(e == null ? undefined : e.ssoMeta, Ii.IDAAS_LOGIN_KEY), Ne(Ne({}, s), {
sameSite: "lax"
The values of those constants:
var Ii = {
COOKIE: "cookie",
OCM_TOKEN_KEY: "ocmJwtToken",
TOKEN_KEY: "__opswat-my-tk",
REFRESH_TOKEN_KEY: "__opswat-my-rt",
CSRF_TOKEN_KEY: "__opswat-my-ct",
IDAAS_LOGIN_KEY: "__opswat-login",
IDAAS_PAYLOAD_KEY: "__opswat-payload-login",
IDAAS_REFRESH_KEY: "__opswat-refresh-login",
IDAAS_SESSION_KEY: "__opswat-session-login",
FIRST_NAME_DEFAULT: "First name - need input",
LAST_NAME_DEFAULT: "Last name - need input",
TOKEN_EXPIRED_TIME: "__opswat-my-tet",
SAML_SESSION: "saml_session",
BOTPRESS_WEBCHAT: "botpress-webchat"
};
Some cases invoke the ui
function, which sets a local storage item:
function ui(e, t) {
if (e) {
return window.localStorage.setItem(e, t);
} else {
return null;
}
}
Meanwhile, the li
function will invoke the set
method of the si
object:
var si = xo.withConverter({
read: function (e, t) {
return e;
},
write: function (e, t) {
return e;
}
});
function li(e, t, n) {
if (e) {
return si.set(e, t, n);
} else {
return null;
}
}
Where xo
is a function defined like this:
var xo = function e(t, n) {
function r(e, r, o) {
if (typeof document != "undefined") {
if (typeof (o = yo({}, n, o)).expires == "number") {
o.expires = new Date(Date.now() + o.expires * 86400000);
}
o.expires &&= o.expires.toUTCString();
e = encodeURIComponent(e).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
var i = "";
for (var a in o) {
if (o[a]) {
i += "; " + a;
if (o[a] !== true) {
i += "=" + o[a].split(";")[0];
}
}
}
return document.cookie = e + "=" + t.write(r, e) + i;
}
}
return Object.create({
set: r,
As we can see, the set
function is the r
function and the r
function will used for setting the cookies. So, the li
function will set the cookies.
Hidden REST API Endpoints
Found some REST API endpoints:
const H = "personal-information";
const U = "preferences";
const W = "/my-information";
const q = `${W}/security`;
const Y = `${W}/${U}`;
const G = `${W}/${H}`;
const X = "/license-management";
const K = `${X}/my-organization`;
const Q = `${X}/customer-organizations`;
`/iframe-pages/licensed-products/:tabPath`;
const J = "/my-organization";
const $ = `${J}/general-information`;
const ee = `${J}/groups`;
const te = `${J}/users`;
const ne = `${J}/application-roles`;
const re = `${J}/security`;
const oe = `${J}/event-history`;
const ie = `${J}/critical-alert-users`;
const ae = "/home";
const se = "/login";
const le = "/register";
const ce = "/reset-password";
const ue = "/change-password";
const de = "/confirm-email";
const pe = "/resend-email";
const fe = "/verify-otp";
const he = "/active";
const me = "/accepted-invite";
const ge = "/mfa";
const ve = "/prduct-downloads";
const ye = "/anti-malware-engine-status/windows";
const xe = "/anti-malware-engine-status/linux";
const be = "/anti-malware-engine-status/packages";
const we = "/no-permission";
const Ce = "/dialog";
const Se = "/payment";
const ke = "/nlv/payment";
const je = "/report-false-detection";
const Ee = `${je}/:tabPath`;
const Ae = `${je}/submit`;
const Te = `${je}/history`;
const Pe = "/support";
const Oe = `${Pe}/all-cases`;
const Me = `${Pe}/submit-case`;
const Ie = "/test-iframe";
const _e = {
"/portal/products": ae,
"/portal/oem": ae,
"/user-management/roles": ne,
"/user-management/users": te,
"/user-profile/personal-information": G,
"/user-profile/product-subscription": Y,
"/inventory/metadefender-kiosk-l1001/instances": "/product-management/inventory/metadefender-kiosk/l-series/instances",
"/inventory/metadefender-kiosk-l1001/groups": "/product-management/inventory/metadefender-kiosk/l-series/groups",
"/home/opswat-neuralyzer": "/home/metadefender-ot-security",
"/home/opswat-client": "/home/metadefender-endpoint",
"/home/endpoint-clients": "/home/metadefender-endpoint-solution",
"/home/metaaccess": "/home/metadefender-it-ot-access",
"/home/metadefender-it-ot-access": "/home/metadefender-it-access",
"/home/metaaccess-nac": "/home/nac",
"/home/secure-ot-access": "/home/metadefender-ot-access-on-premise",
"/home/nac": "/home/metadefender-nac",
"/home/ot-drive-tool-kit": "/home/metadefender-drive-tool-kit",
"/home/opswat-filescan-sandbox": "/home/metadefender-sandbox",
"/home/opswat-endpoint-security-sdk": "/home/metadefender-endpoint-security-sdk",
"/home/opswat-netwall": "/home/metadefender-netwall",
"/home/netwall-tp": "/home/transfer-guard",
"/home/netwall-tp-blue": "/home/transfer-guard-blue",
"/home/netwall-tp-red": "/home/transfer-guard-red",
"/home/vulnerability-definitions-for-central-management": "/home/vulnerability-definitions",
"/home/opswat-otfuse": "/home/otfuse",
"/home/metadefender-industrial-firewall-ips": "/home/otfuse",
"/home/endpoint-standalone": "/home/endpoint-validation",
"/my-licenses": K,
"/support-service": Pe,
"/support-services": Pe,
"/support-service/submit-case": Me,
"/support-service/all-cases": Oe,
"/support-services/submit-case": Me,
"/support-services/all-cases": Oe