background

JS reverse is really a technical work, there is a public account has made a high price of paid courses. But the funds are limited, under the determination to buy. So the course all can look at the video again, peep got some JS reverse skills, for me this little white, or very eye-opening.

Today, I continued to track the anti-stripping process of a bidding website. Using the single step debugging function of JS, I successfully located the place where THE URL was changed before AJAX sent requests, which is also a big progress.

Conditional breakpoints and stack location

It was assumed that there was a hook event in the Ajax request that caused the request URL parameter to change, but no evidence was found. After stealing some JS reverse tricks, using conditional breakpoints and stack call chains, finally located.

First, in the debug panel to the right of Sources, enable any Ajax request breakpoint:Step 2, refresh the page, enter the breakpoint function, jquery.min.js file, click on the lower left corner{}If you format it, you can clearly see where the breakpoint is:Using the stack chain, looking backwards at the caller is ajax’s send method:thissendMethod does not modify the URL parameters, so continue aheadg.openThere is an interruption point where the function it interprets finally completes the logic of resetting URL parameters.

_$zh () {open/send () {open/send ();

Rewrite Ajax open

After using conditional breakpoints, I step through the trace and finally find a way to change the URL path before ajax is sent, and continue analyzing its flow.

First, the websitesendMethods have hooks, and in ajax’s send logic,openIs interpreted as another function [whose name changes every time the page is refreshed] :Step two, continue to locate_$egWhere the function is defined:Third, look at its code

function _$eg() {
    _$6f();
    var _$Rc = _$ep(arguments[1]);
    arguments[1] = _$Rc._$s3;
    this._$Wl = _$Rc._$Wl;
    return _$UA[_$uT[43]] (this.arguments);
}
Copy the code

Be careful. There’s a smoke screen, a sight_6f()A function is not a real function; it is interpreted as:Search within the current JS fragment_$CUFunction definition:

function _$CU() {
    var _$lh = [65];
    Array.prototype.push.apply(_$lh, arguments);
    return _$wV.apply(this, _$lh);
}
Copy the code

Continuing with _$wV is a long obfuscating JS that doesn’t affect the request parameters, leave it at that.

Where to modify the URL

Behind the wordsvar _$Rc = _$ep(arguments[1])After the function call, the URL of the Ajax request changes with two additional parameters:

Locate this method:

function _$ep(_$SZ, _$uA) {
      var _$G_, _$uG = null;
      var _$Rc = _$SZ;
      function _$kw(_$Mj, _$jU) {
          var _$Rc = [];
          var _$fL = ' ';
          var _$nC = _$Fm(_$Q5());
          _$Rc = _$Rc[_$uT[4]](_$jU, _$Mj, _$uA || 0, _$nC);
          var _$eg = _$5Z(743.6.true, _$Rc);
          var _$x$ = _$EJ + _$eg;
          _$uG = _$hx(_$4T(_$x$), 2);
          return _$aW[_$uT[9]](_$fL, _$3a, _$uT[3], _$x$);
      }
      function _$fL() {
          try {
              if (typeof_$SZ ! == _$uT[6])
                  _$SZ += ' ';
              _$G_ = _$Vr(_$SZ);
              if(_$O0) { _$SZ = _$RJ(_$SZ, _$G_); }}catch (_$Rc) {
              return;
          }
          if (_$G_ === null || _$G_._$R9 >= 4) {
              _$5Z(773.6);
              return;
          }
          if (_$8H(_$G_)) {
              _$5Z(773.6);
              return;
          }
          _$SZ = _$G_._$Sy + _$G_._$lJ;
          var _$fL = _$Rf(_$G_);
          var _$nC = _$fL ? _$uT[7] + _$fL : ' ';
          var _$eg = _$3f(_$91(_$nZ(_$G_._$$G + _$nC)));
          var _$x$ = 0;
          if (_$G_._$_B) {
              _$x$ |= 1;
          }
          _$SZ += _$uT[7] + _$kw(_$x$, _$eg, _$uA);
          if (_$fL.length > 0) {
              if (_$HV && _$HV <= 8) {
                  _$SZ = _$s9(_$SZ);
              }
              if(! (_$Zu &1024)) {
                  _$fL = _$s9(_$fL);
              }
              _$fL = _$uT[62] + _$E6(_$fL, _$uG, 4);
          }
          _$SZ += _$fL;
      }
      function _$nC(_$Mj) {
          _$40(2, _$nP(5));
          if (_$uG === null || _$hS(_$G_) === false) {
              return _$Mj;
          }
          if (typeof _$Mj === _$uT[6] | |typeof _$Mj === _$uT[615] | |typeof _$Mj === _$uT[77]) {
              _$Mj = _$E6(_$Mj, _$uG, 5);
          }
          return _$Mj;
      }
      function _$eg(_$Mj, _$jU) {
          if ((_$Mj === 'get' || _$Mj === _$uT[247]) && (_$yA & 1) && (_$Zu & 8192) && !(_$G_ && (_$G_._$R9 >= 5 || _$G_._$_B))) {
              if (_$jU === _$Xm || _$jU === null || _$jU === ' ')
                  _$jU = _$uT[299];
              if (_$jU === _$uT[299]) {
                  return_$jU; }}return ' ';
      }
      _$fL();
      return {
          _$7W: _$Rc,
          _$s3: _$SZ,
          _$Wl: _$nC,
          _$Wm: _$eg
      };
}
Copy the code

Follow here really is incapable of action, this pile of unknown so JS, may be the legend of the use of Caesar password confused JS.

The revelation of

First, if the breakpoint stays too long, even if the browser clicks, it will appear403 ForbiddenThe problem:Perhaps there is timestamp information in this logic.

Second, call the function that modifs the URL before open to retrieve the following parameters:

In theory, reverse interpretation of the above section of JS, using Java to achieve the return statement to get the corrected URL, you can solve the problem. The challenge is how do you use your code to locate the open hook function returned by the current page before emulating the Ajax request? It is dynamically generated, so you still need to decrypt the JS fragment in which the hook function resides.

To tell the truth, this infinite debugger means much better than the last introduction, even if you know that you can debug, but in fact it is a no word book! Oh, my God, help me!