国家税务总局全国增值税发票查验平台网站js逆向分析

本文教程针对的是2021年7月2日时国税查验平台的js分析,其中版本号为V2.0.06_009。主要分析内容为key9和flwq39以及fplx这3个参数的算法,其中key9分为获取验证码阶段和查验阶段,算法有所区别,flwq39同理。

教程开始:

一、官方网址

https://inv-veri.chinatax.gov.cn/index.html

二、请求分析

国税查验平台请求共分为2个,第一个请求获取验证码,第二个请求为输入验证码后查验数据并返回发票详细信息。

第一步:安装证书

基础:谷歌浏览器

首先需要安装证书,建议选择自动安装,在某些教程中可能选择手动安装,以便于使用ast工具挂代理找内存数据,但是这里我们采用一种新的方法来解决js逆向问题,因此那种方便用那种。

国家税务总局全国增值税发票查验平台网站js逆向分析

第二步:抓包

基础:谷歌浏览器+开发者工具+js基础知识

我们使用开发者工具或按F12打开谷歌浏览器的开发者工具,请注意尽量在网页加载完成后打开开发者工具,界面如下:

国家税务总局全国增值税发票查验平台网站js逆向分析

官方很给力,直接debug了,至于如何去掉断点,可以参考百度上的其他教程,这里给出一个办法,上图中点击数据1所处位置,使其颜色为蓝色,点击2或者点击上方的debug恢复按钮。此时,我们成功绕过了debug,但是特别注意尽量关闭其他无用软件或者网页,因为在后面的操作中,会感到特别卡顿。

我们在发票代码输入框和发票号码中输入合法的数据,并在开发者工具的netword模块,观察所发送的请求包:

https://fpcy.anhui.chinatax.gov.cn/NWebQuery/yzmQuery?callback=jQuery11020854931324645166_1625223145135&fpdm=034012000211&fphm=12345678&r=0.28901229909781767&v=V2.0.06_009&nowtime=1625223446708&publickey=1625223446708&key9=ec213f1e1aa579511f5d58f09a01a5a2&_=1625223145136&flwq39=LdjaQwXUtzKjxpXQ%2FmD7KCBtBMP7lqfc7uBJNuxAumYpT9mjp90BloLfM4V6KKuD4GWdYCxRLLjJX9a1YrNy7Bs95NmSWQmpc1VAibkeG3HydXc0r9xsRc%2BkIsPWeHrFk3PYAP6k8tAcTJzoIdlhctD8wOUVXOUwczcMJW6WiF0%3D

在这个请求中,分为url的网址前缀部分和尾部参数,其中尾部参数如下:

callback=固定值
fpdm=发票代码
fphm=发票号码
r=随机数
V=版本号
nowtime=当前时间减去1分钟
publickey=当前时间减去1分钟
key9=加密参数
_=可为固定值
flwq39=加密参数

如果你观察过会发现,不同地区的发票,请求的地址不同,如这里是anhui。该请求的前缀部分在一个js文件中,如图:

国家税务总局全国增值税发票查验平台网站js逆向分析

但是,很不幸,当你打开这个文件时,你会发现混淆了,不过很容易发现是sojson的样子,这并不影响我们逆向,我们使用http://tool.yuanrenxue.com/decode_obfuscator这个网站可以解密这些js代码,尽管解密的代码看着很头疼,但是已经比原始的好太多了。

国家税务总局全国增值税发票查验平台网站js逆向分析

解密后可以得到各个地区的ip和网址以及对应的地区代码:

0: {code: "1100", sfmc: "北京", Ip: "https://fpcy.beijing.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.beijing.chinatax.gov.cn:443"}
1: {code: "1200", sfmc: "天津", Ip: "https://fpcy.tjsat.gov.cn:443/NWebQuery", address: "https://fpcy.tjsat.gov.cn:443"}
2: {code: "1300", sfmc: "河北", Ip: "https://fpcy.hebei.chinatax.gov.cn/NWebQuery", address: "https://fpcy.hebei.chinatax.gov.cn"}
3: {code: "1400", sfmc: "山西", Ip: "https://fpcy.shanxi.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.shanxi.chinatax.gov.cn:443"}
4: {code: "1500", sfmc: "内蒙古", Ip: "https://fpcy.neimenggu.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.neimenggu.chinatax.gov.cn:443"}
5: {code: "2100", sfmc: "辽宁", Ip: "https://fpcy.liaoning.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.liaoning.chinatax.gov.cn:443"}
6: {code: "2102", sfmc: "大连", Ip: "https://sbf.dalian.chinatax.gov.cn:8402/NWebQuery", address: "https://sbf.dalian.chinatax.gov.cn:8402"}
7: {code: "2200", sfmc: "吉林", Ip: "https://fpcy.jilin.chinatax.gov.cn:4432/NWebQuery", address: "https://fpcy.jilin.chinatax.gov.cn:4432"}
8: {code: "2300", sfmc: "黑龙江", Ip: "https://fpcy.heilongjiang.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.heilongjiang.chinatax.gov.cn:443"}
9: {code: "3100", sfmc: "上海", Ip: "https://fpcy.shanghai.chinatax.gov.cn:1001/NWebQuery", address: "https://fpcy.shanghai.chinatax.gov.cn:1001"}
10: {code: "3200", sfmc: "江苏", Ip: "https://fpcy.jiangsu.chinatax.gov.cn:80/NWebQuery", address: "https://fpcy.jiangsu.chinatax.gov.cn:80"}
11: {code: "3300", sfmc: "浙江", Ip: "https://fpcy.zhejiang.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.zhejiang.chinatax.gov.cn:443"}
12: {code: "3302", sfmc: "宁波", Ip: "https://fpcy.ningbo.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.ningbo.chinatax.gov.cn:443"}
13: {code: "3400", sfmc: "安徽", Ip: "https://fpcy.anhui.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.anhui.chinatax.gov	.cn:443"}
14: {code: "3500", sfmc: "福建", Ip: "https://fpcy.fujian.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.fujian.chinatax.gov.cn:443"}
15: {code: "3502", sfmc: "厦门", Ip: "https://fpcy.xiamen.chinatax.gov.cn/NWebQuery", address: "https://fpcy.xiamen.chinatax.gov.cn"}
16: {code: "3600", sfmc: "江西", Ip: "https://fpcy.jiangxi.chinatax.gov.cn:82/NWebQuery", address: "https://fpcy.jiangxi.chinatax.gov.cn:82"}
17: {code: "3700", sfmc: "山东", Ip: "https://fpcy.shandong.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.shandong.chinatax.gov.cn:443"}
18: {code: "3702", sfmc: "青岛", Ip: "https://fpcy.qingdao.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.qingdao.chinatax.gov.cn:443"}
19: {code: "4100", sfmc: "河南", Ip: "https://fpcy.henan.chinatax.gov.cn/NWebQuery", address: "https://fpcy.henan.chinatax.gov.cn"}
20: {code: "4200", sfmc: "湖北", Ip: "https://fpcy.hubei.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.hubei.chinatax.gov.cn:443"}
21: {code: "4300", sfmc: "湖南", Ip: "https://fpcy.hunan.chinatax.gov.cn:8083/NWebQuery", address: "https://fpcy.hunan.chinatax.gov.cn:8083"}
22: {code: "4400", sfmc: "广东", Ip: "https://fpcy.guangdong.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.guangdong.chinatax.gov.cn:443"}
23: {code: "4403", sfmc: "深圳", Ip: "https://fpcy.shenzhen.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.shenzhen.chinatax.gov.cn:443"}
24: {code: "4500", sfmc: "广西", Ip: "https://fpcy.guangxi.chinatax.gov.cn:8200/NWebQuery", address: "https://fpcy.guangxi.chinatax.gov.cn:8200"}
25: {code: "4600", sfmc: "海南", Ip: "https://fpcy.hainan.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.hainan.chinatax.gov.cn:443"}
26: {code: "5000", sfmc: "重庆", Ip: "https://fpcy.chongqing.chinatax.gov.cn:80/NWebQuery", address: "https://fpcy.chongqing.chinatax.gov.cn:80"}
27: {code: "5100", sfmc: "四川", Ip: "https://fpcy.sichuan.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.sichuan.chinatax.gov.cn:443"}
28: {code: "5200", sfmc: "贵州", Ip: "https://fpcy.guizhou.chinatax.gov.cn:80/NWebQuery", address: "https://fpcy.guizhou.chinatax.gov.cn:80"}
29: {code: "5300", sfmc: "云南", Ip: "https://fpcy.yunnan.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.yunnan.chinatax.gov.cn:443"}
30: {code: "5400", sfmc: "*", Ip: "https://fpcy.xztax.gov.cn:81/NWebQuery", address: "https://fpcy.xztax.gov.cn:81"}
31: {code: "6100", sfmc: "陕西", Ip: "https://fpcy.shaanxi.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.shaanxi.chinatax.gov.cn:443"}
32: {code: "6200", sfmc: "甘肃", Ip: "https://fpcy.gansu.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.gansu.chinatax.gov.cn:443"}
33: {code: "6300", sfmc: "青海", Ip: "https://fpcy.qinghai.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.qinghai.chinatax.gov.cn:443"}
34: {code: "6400", sfmc: "宁夏", Ip: "https://fpcy.ningxia.chinatax.gov.cn:443/NWebQuery", address: "https://fpcy.ningxia.chinatax.gov.cn:443"}
35: {code: "6500", sfmc: "*", Ip: "https://fpcy.xj-n-tax.gov.cn:443/NWebQuery", address: "https://fpcy.xj-n-tax.gov.cn:443"}

回到抓包中,我们观察到这时发送了一个获取验证码的请求:

国家税务总局全国增值税发票查验平台网站js逆向分析

注意到通过分析这个url,我们发现请求来自如下图,我们注意到getyzmxx这个函数,来自eab23.js这个文件里,我们提取这个文件使用ob解密。

国家税务总局全国增值税发票查验平台网站js逆向分析

ob解密后的数据如下:

var _0x14658c = function () {
  var _0x2253f1 = true;
  return function (_0x41c5d5, _0x508a27) {
    var _0x47fbda = _0x2253f1 ? function () {
      if (_0x508a27) {
        var _0x6b4e27 = _0x508a27["apply"](_0x41c5d5, arguments);

        _0x508a27 = null;
        return _0x6b4e27;
      }
    } : function () {};

    _0x2253f1 = false;
    return _0x47fbda;
  };
}();

var _0x59e564 = _0x14658c(this, function () {
  var _0x595419 = function () {
    return "dev";
  },
      _0x4c5231 = function () {
    return "window";
  };

  var _0x1842a8 = function () {
    var _0x21d015 = new RegExp("\\w+ *\\(\\) *{\\w+ *['|\"].+['|\"];? *}");

    return !_0x21d015["test"](_0x595419["toString"]());
  };

  var _0x113bb3 = function () {
    var _0x326224 = new RegExp("(\\\\[x|u](\\w){2,4})+");

    return _0x326224["test"](_0x4c5231["toString"]());
  };

  var _0x185d70 = function (_0x4ac461) {
    var _0x557ade = 0;

    if (_0x4ac461["indexOf"](false)) {
      _0x3cbd92(_0x4ac461);
    }
  };

  var _0x3cbd92 = function (_0x2bb9d8) {
    var _0x5f4806 = 3;

    if (_0x2bb9d8["indexOf"]("true"[3]) !== _0x5f4806) {
      _0x185d70(_0x2bb9d8);
    }
  };

  if (!_0x1842a8()) {
    if (!_0x113bb3()) {
      _0x185d70("ind\u0435xOf");
    } else {
      _0x185d70("indexOf");
    }
  } else {
    _0x185d70("ind\u0435xOf");
  }
});

_0x59e564();

var yzmWait = 2;
var retrycount = 0;
$(document)["ready"](function () {
  $("#fpdm")["blur"](function () {
    retrycount = 0;
  });
});

function yzmTime(_0x5c47fb) {
  if (yzmWait == 0) {
    $("#yzm_unuse_img")["hide"]();
    $("#yzm_img")["show"]();
    yzmWait = 60;
  } else {
    if (yzmWait == 2) {
      $("#yzm_unuse_img")["show"]();
      $("#yzm_img")["hide"]();
    }

    yzmWait--;
    setTimeout(function () {
      yzmTime(_0x5c47fb);
    }, 1000);
  }
}

function getYzmXx() {
  $["pricode"]["clearA"]();
  show_yzm = "1";

  var _0x31767b = $("#fpdm")["val"]()["trim"]();

  var _0x4dfb9 = getSwjg(_0x31767b, 0);

  var _0x3297c1 = _0x4dfb9[1] + "/yzmQuery";

  var _0x41afd2 = showTime()["toString"]();

  var _0x1912a2 = $("#fpdm")["val"]()["trim"]();

  var _0x478041 = $("#fphm")["val"]()["trim"]();

  var _0x1a5014 = $("#kjje")["val"]()["trim"]();

  var _0x70138f = Math["random"]();

  var _0x1d5629 = _0x4dfb9[2];
  var _0x18c20a = {
    "fpdm": _0x1912a2,
    "fphm": _0x478041,
    "r": _0x70138f,
    "v": VVV,
    "nowtime": _0x41afd2,
    "area": _0x1d5629,
    "publickey": _0x41afd2,
    "key9": $["nnyd"]["yzm"](_0x1912a2, _0x478041, _0x41afd2)
  };
  $["ajaxSetup"]({
    "cache": false
  });
  yzmFlag = 1;
  $["ajax"]({
    "type": "post",
    "url": _0x3297c1,
    "data": _0x18c20a,
    "dataType": "jsonp",
    "jsonp": "callback",
    "success": function (_0x135eb2) {
      if (_0x135eb2["hasOwnProperty"]("data")) {
        _0x135eb2 = _0x135eb2["data"];
        _0x135eb2 = replaceStr(_0x135eb2, _0x41afd2);
        _0x135eb2 = Base64["decode"](_0x135eb2);
        _0x135eb2 = eval("(" + _0x135eb2 + ")");
      }

      delayFlag = "1";
      var _0x2651d3 = _0x135eb2["key1"];
      var _0x1a96a9 = _0x135eb2["key2"];
      var _0x2b0c56 = _0x135eb2["key3"];
      var _0x1769c2 = _0x135eb2["key4"];
      var _0x483079 = _0x135eb2["key5"];
      var _0x2e8ee0 = _0x135eb2["key6"];

      if (_0x483079 == "2") {
        oldweb = 2;
      } else {
        if (_0x483079 == "1") {
          oldweb = 1;
        }
      }

      if (_0x2651d3 == "003") {
        jAlert("\u9A8C\u8BC1\u7801\u8BF7\u6C42\u6B21\u6570\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF71\u5206\u949F\u540E\u518D\u8BD5\uFF01", "\u8B66\u544A");
        $("#yzm_img")["hide"]();
      } else {
        if (_0x2651d3 == "005") {
          jAlert("\u975E\u6CD5\u8BF7\u6C42!", "\u8B66\u544A");
        } else {
          if (_0x2651d3 == "010") {
            jAlert("\u7F51\u7EDC\u8D85\u65F6\uFF0C\u8BF7\u91CD\u8BD5\uFF01(01)", "\u8B66\u544A");
          } else {
            if (_0x2651d3 == "fpdmerr") {
              jAlert("\u8BF7\u8F93\u5165\u5408\u6CD5\u53D1\u7968\u4EE3\u7801!", "\u8B66\u544A");
            } else {
              if (_0x2651d3 == "024") {
                jAlert("24\u5C0F\u65F6\u5185\u9A8C\u8BC1\u7801\u8BF7\u6C42\u592A\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\uFF01", "\u8B66\u544A");
                $("#yzm_img")["hide"]();
              } else {
                if (_0x2651d3 == "016") {
                  jAlert("\u670D\u52A1\u5668\u63A5\u6536\u7684\u8BF7\u6C42\u592A\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\uFF01", "\u8B66\u544A");
                  $("#yzm_img")["hide"]();
                } else {
                  if (_0x2651d3 == "020") {
                    jAlert("\u7531\u4E8E\u67E5\u9A8C\u884C\u4E3A\u5F02\u5E38\uFF0C\u6D89\u5ACC\u8FDD\u89C4\uFF0C\u5F53\u524D\u65E0\u6CD5\u4F7F\u7528\u67E5\u9A8C\u670D\u52A1\uFF01", "\u63D0\u793A");
                  } else {
                    if (_0x2651d3 == "errv") {
                      jAlert("\u5F53\u524D\u9875\u9762\u7248\u672C\u8F83\u4F4E\uFF0C\u8BF7\u6309CTRL-F5\u5237\u65B0\u9875\u9762\uFF01", "\u63D0\u793A");
                    } else {
                      if (_0x2651d3 != "") {
                        setTimeout(function () {
                          $("#yzm_img")["attr"]("src", "data:image/png;base64," + _0x2651d3);
                          $("#yzm_unuse_img")["attr"]("src", "data:image/png;base64," + _0x2651d3);

                          if (_0x1769c2 == "00") {
                            $("#yzminfo")["text"]("\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\u6587\u5B57");
                          } else {
                            if (_0x1769c2 == "01") {
                              $("#yzminfo")["html"]("\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\u56FE\u7247\u4E2D<font color=\"red\" size=\"4\" style=\"background:#C0C0C0\">\u7EA2\u8272</font>\u6587\u5B57");
                            } else {
                              if (_0x1769c2 == "02") {
                                $("#yzminfo")["html"]("\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\u56FE\u7247\u4E2D<font color=\"yellow\" size=\"4\" style=\"background:#C0C0C0\">\u9EC4\u8272</font>\u6587\u5B57");
                              } else {
                                if (_0x1769c2 == "03") {
                                  $("#yzminfo")["html"]("\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\u56FE\u7247\u4E2D<font color=\"blue\" size=\"4\" style=\"background:#C0C0C0\">\u84DD\u8272</font>\u6587\u5B57");
                                }
                              }
                            }
                          }

                          yzmSj = _0x1a96a9;
                          jmmy = _0x2b0c56;
                          key6 = _0x2e8ee0;
                        }, 500);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "timeout": 5000,
    "error": function (_0x11ade1, _0x2c42b8, _0x3a7f30) {
      if (retrycount == 9) {
        jAlert("\u7CFB\u7EDF\u7E41\u5FD9\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5!", "\u63D0\u793A");
      } else {
        retrycount = retrycount + 1;
        getYzmXx();
      }
    }
  });
  yzmWait = 2;
  yzmTime($("#yzm_img"));
}

function showTime() {
  var _0x229b47 = new Date();

  var _0x2be691 = _0x229b47["getTime"]();

  return _0x2be691;
}

我们注意到key9值的位置,

$["nnyd"]["yzm"](_0x1912a2, _0x478041, _0x41afd2)

这里需要知道$["nnyd"]["yzm"]的具体函数,分析后如下:


  _0x4abed0["prototype"]["yzm"] = function (_0x4a04f9, _0x1fcc0a, _0x4473d7) {
    var _0x3a01ad = new Array(3);

    _0x3a01ad[0] = _0x4a04f9 + _0x1fcc0a;
    _0x3a01ad[1] = _0x4a04f9 + _0x1fcc0a + _0x1fcc0a + _0x4a04f9;
    _0x3a01ad[2] = _0x4a04f9 + _0x4a04f9 + _0x1fcc0a + _0x4a04f9 + _0x1fcc0a + _0x4a04f9;

    var _0x155fec = _0x3a01ad[0]["substring"](0, 8);

    var _0x32d768 = _0x3a01ad[0]["substring"](8);

    var _0x559889 = _0x1e3a12(_0x155fec);

    var _0x5a173e = _0x559889["length"];

    for (var _0x2e3884 = 0; _0x2e3884 < _0x5a173e; _0x2e3884++) {
      for (var _0x39a07a = _0x2e3884 + 1; _0x39a07a < _0x5a173e; _0x39a07a++) {
        if (_0x559889[_0x2e3884] > _0x559889[_0x39a07a]) {
          _0x3f015b(_0x559889, _0x2e3884, _0x39a07a);
        }
      }
    }

    _0x155fec = _0x328421(_0x559889);

    var _0x3cf5d7 = _0x1e3a12(_0x32d768);

    var _0x5a173e = _0x3cf5d7["length"];
    var _0x38743f = 0;

    for (var _0x2e3884 = 0; _0x2e3884 < _0x5a173e; _0x2e3884++) {
      _0x38743f = _0x2e3884;

      for (var _0x39a07a = _0x2e3884 + 1; _0x39a07a < _0x5a173e; _0x39a07a++) {
        if (_0x3cf5d7[_0x38743f] > _0x3cf5d7[_0x39a07a]) {
          _0x38743f = _0x39a07a;
        }
      }

      _0x3f015b(_0x3cf5d7, _0x2e3884, _0x38743f);
    }

    _0x32d768 = _0x328421(_0x3cf5d7);

    var _0x8300db = _0x205ff1["encrypt"](_0x155fec) + _0x32d768;

    var _0x15339a = _0x3a01ad[1]["substring"](0, 9);

    var _0x3c7f1d = _0x3a01ad[1]["substring"](9, 17);

    var _0x1dd08a = _0x3a01ad[1]["substring"](17);

    var _0x591ade = _0x1e3a12(_0x15339a);

    var _0x5a173e = _0x591ade["length"];
    var _0x41c5e3 = 0;

    for (var _0x2e3884 = 0; _0x2e3884 < _0x5a173e; _0x2e3884++) {
      _0x41c5e3 = _0x2e3884;

      for (var _0x39a07a = _0x2e3884 + 1; _0x39a07a < _0x5a173e; _0x39a07a++) {
        if (_0x591ade[_0x41c5e3] > _0x591ade[_0x39a07a]) {
          _0x41c5e3 = _0x39a07a;
        }
      }

      _0x3f015b(_0x591ade, _0x2e3884, _0x41c5e3);
    }

    _0x15339a = _0x328421(_0x591ade);

    var _0x185cf9 = _0x1e3a12(_0x3c7f1d);

    var _0x2fa209 = _0x185cf9["length"];

    _0x3ad848["yzmdelay"](_0x4a04f9, _0x1fcc0a, _0x4473d7);

    console["log"]("\u9A8C\u8BC1\u7801\u9ED8\u8BA4\u5EF6\u65F6:312");

    for (var _0x2e3884 = 0; _0x2e3884 < _0x2fa209; _0x2e3884++) {
      for (var _0x39a07a = _0x2e3884 + 1; _0x39a07a < _0x2fa209; _0x39a07a++) {
        if (_0x185cf9[_0x2e3884] > _0x185cf9[_0x39a07a]) {
          _0x3f015b(_0x185cf9, _0x2e3884, _0x39a07a);
        }
      }
    }

    _0x3c7f1d = _0x328421(_0x185cf9);

    var _0x30d382 = _0x1e3a12(_0x1dd08a);

    var _0x3a8185 = _0x30d382["length"];

    for (var _0x2e3884 = 1; _0x2e3884 < _0x3a8185; _0x2e3884++) {
      for (var _0x39a07a = _0x2e3884; _0x39a07a > 0; _0x39a07a--) {
        if (_0x30d382[_0x39a07a] < _0x30d382[_0x39a07a - 1]) {
          _0x3f015b(_0x30d382, _0x39a07a, _0x39a07a - 1);
        } else {
          break;
        }
      }
    }

    _

这里只展示了部分数据,同时注意到一个参数,后面用得到:

0x5ecc18["setPublicKey"]("MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCjrcnzPya+QS6i5QND2EsIcrsP3/NRwgcYoaNyowpuIzQGDIySfhifm/+j41vJqwKd0D5Otjn6lF5mpUz0zvgMlVco5YytXIbBR8n7WfJ/1W4kTWYr9PM/sT3P23fS3xt13NHln7XgEjP7juv6z52OQOKxYKL/LFxoLkhQpUydWQIBEQ==");

如果有经验,你会知道可能和RSA加密相关,事实也是如此,上面已经对key9的算法位置分析清楚了,下面对flwq39进行分析,实际上,flwq39也是在这个文件中,我使用vscode对解密后的js代码进行了格式化,并查找了flwq39这个关键字,发现如图:

国家税务总局全国增值税发票查验平台网站js逆向分析

因此,我们继续分析会发现该参数是在请求前拼接完成的,并且关键字本身被替换了:

国家税务总局全国增值税发票查验平台网站js逆向分析

 反向找到调用的函数就会发现最终是调用了RSA加密算法,其中PublicKey就是

MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCjrcnzPya+QS6i5QND2EsIcrsP3/NRwgcYoaNyowpuIzQGDIySfhifm/+j41vJqwKd0D5Otjn6lF5mpUz0zvgMlVco5YytXIbBR8n7WfJ/1W4kTWYr9PM/sT3P23fS3xt13NHln7XgEjP7juv6z52OQOKxYKL/LFxoLkhQpUydWQIBEQ==

在验证码获取后返回包如下:

jQuery11020854931324645166_1625223145135({"key1":"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","key2":"2021-07-02 18:34:48","key3":"43017c78ec891a4b9406501694f0b479","key4":"01","key5":"2","key6":"402887f17a53027c017a66d4d62d72d0"})

 其中key1是经过base64编码的图片数据,key2是验证码的时间,另外注意到key3和key4及key6。

其中key4分为4种情况分别为输入全部、黄色、红色、蓝色,对应00,01,02,03。余下的参数在验证阶段用到。

同理,在查验阶段,请求如下:

https://fpcy.anhui.chinatax.gov.cn/NWebQuery/vatQuery?callback=jQuery11020854931324645166_1625223145135&key1=034012000211&key2=12345678&key3=20210702&key4=123456&fplx=10&yzm=MK&yzmSj=2021-07-02+18%3A34%3A48&index=43017c78ec891a4b9406501694f0b479&key6=402887f17a53027c017a66d4d62d72d0&publickey=2021-07-02+18%3A34%3A48&key9=ac558f9ae05a94c21dc504f5d8882b9d&_=1625223145137&flwq39=Ky8pYUqln7zaEZcxF9XZw3fAsiOM%2F92RmTxy%2BNAtDo4f1h3c1yHQJZNESl5Nz9Xq5Mu7bEeBkFlPgerOBnR1pnLviLn4WLkMTtzsLy%2BMe2wPu%2B%2FFaiszckIGS%2F1Z5YZ4zusosj68YLZ0hRk53UWbrWz9xg%2BC3XRGwEWyqbzg0XE%3D

这里注意到

key1=发票代码
key2=发票号码
key3=发票日期
key4=校验码或者不含税的金额
fplx=发票类型,一个函数
yzm=验证码
yzmsj=获取验证码请求的返回包里的key2
index=获取验证码请求的返回包里的Key3
key6=获取验证码请求的返回包里的Key6
publickey=验证码时间
key9=加密参数
flwq39=加密参数

这里的key9和flwq39在

$["nnyd"]["cy"]

这个对应的函数中,key9和flwq39算法和上面的类似。

此外注意到fplx这种参数,也在这几个js文件中,这里给出具体的函数名:

var code=["144031539110", "131001570151", "133011501118", "111001571071"];
    function alxd(a) {
    var b;
    var c = "99";
    if (a.length == 12) {
        b = a.substring(7, 8);
        for (var i = 0; i < code.length; i++) {
            if (a == code[i]) {
                c = "10";
                break
            }
        }
        if (c == "99") {
            if (a.charAt(0) == '0' && a.substring(10, 12) == '11') {
                c = "10"
            }
            if (a.charAt(0) == '0' && (a.substring(10, 12) == '04' || a.substring(10, 12) == '05')) {
                c = "04"
            }
            if (a.charAt(0) == '0' && (a.substring(10, 12) == '06' || a.substring(10, 12) == '07')) {
                c = "11"
            }
            if (a.charAt(0) == '0' && a.substring(10, 12) == '12') {
                c = "14"
            }
        }
        if (c == "99") {
            if (a.substring(10, 12) == '17' && a.charAt(0) == '0') {
                c = "15"
            }
            if (c == "99" && b == 2 && a.charAt(0) != '0') {
                c = "03"
            }
        }
    } else if (a.length == 10) {
        b = a.substring(7, 8);
        if (b == 1 || b == 5) {
            c = "01"
        } else if (b == 6 || b == 3) {
            c = "04"
        } else if (b == 7 || b == 2) {
            c = "02"
        }
    }
    return c
}

通过使用php的v8js拓展,我们可以实现接口编写:

国家税务总局全国增值税发票查验平台网站js逆向分析

国家税务总局全国增值税发票查验平台网站js逆向分析

二者结果一致。

至此,全部参数已经解密完毕,有需要的可联系本人有偿提供具体源代码等。联系方式QQ:193011603
 

上一篇:数学建模如何查找数据?


下一篇:几个实用的生活服务网站和APP