当前位置:网站首页>Per capita Swiss number series, Swiss number 4 generation JS reverse analysis
Per capita Swiss number series, Swiss number 4 generation JS reverse analysis
2022-07-06 23:22:00 【VIP_ CQCRE】
This is a 「 Attacking Coder」 Of the 656 Technology sharing
author :K The little elder brother
source :K Brother reptile
“
It is necessary to read this article 13 minute .
”Statement
All the contents in this article are only for learning and communication , Not for any other purpose , The complete code is not provided , The content of the package 、 Sensitive website 、 The data interface has been desensitized , It is strictly prohibited to use for commercial and illegal purposes , Otherwise, all the consequences have nothing to do with the author !
This article is forbidden to be reproduced without permission , Prohibit any secondary dissemination after modification , Any accident caused by unauthorized use of the technology explained in this article , The author is not responsible , If there is infringement , Please be in the official account. 【K Brother reptile 】 Contact the author to delete it immediately !
Preface
Swiss dynamic security Botgate( Robot firewall ) With “ Dynamic security ” Technology is the core , Through dynamic encapsulation 、 Dynamic validation 、 Dynamic confusion 、 Dynamic token and other technologies continuously and dynamically transform the underlying code of the server web page , Increase server behavior “ Unpredictability ”, It realizes the omni-directional from the client side to the server side “ Active protection ”, For all kinds of Web、HTML5 Provide strong security protection .
Rayleigh number Botgate It is mostly used in government and enterprises 、 Finance 、 Carrier industry , It was once regarded as climbing the ceiling , With the increasing number of reverse bosses in recent years , Relevant reverse articles also emerge in endlessly , It's really the age of Swiss per capita , Here also thanks for things like Nanda、 Lazy God and other reverse bosses , Unveil the mystery of ruishu , The experience summed up made later people take many detours less .
There are basically the following methods for crossing Rayleigh number : Automation tools ( To hide characteristic values )、RPC The remote invocation 、JS reverse ( Hard deduction code and supplementary environment ), This article introduces JS Reverse hard deduction code , Introduce as many details as possible .
The characteristics of Rayleigh number and the differences between different versions
For the vast majority of websites that use RSL , It has the following characteristics ( There may be special versions that are different , First, just look at the mainstream ):
1、 Open developer tools (F12) There will be two typical infinite debugger:
2、 Rayleigh number JS Obfuscate code , Variable 、 Method names are mostly similar to _$xx
, There are many if-else
control flow , The new Swiss number may also have jsvmp And the situation of many ternary expressions :
3、 Look at the request , There will be three typical requests , The first request response code is 202( Rayleigh number 3、4 generation ) perhaps 412( Rayleigh number 5 generation ), Then request a separate JS file , Then re request the page , Other follow-up XHR In request , With a suffix , The value of this suffix is determined by JS Generated , It changes every time , The first number of the suffix value is the Swiss number version , such as MmEwMD=4xxxxx
Namely 4 Dari number ,bX3Xf9nD=5xxxxx
Namely 5 Dari number :
4、 see Cookie, Rayleigh number 3、4 Replace with T and S The two at the end Cookie, Among them S At the beginning Cookie For the first time 201 That request returned , With T At the beginning Cookie By JS Generated , Dynamic ,T and S The front is usually followed by 80 or 443 The number of ,Cookie The first number of the value is the version of Rayleigh number ( Why can we judge the version by the first number ? Won't the first number of the same version change ? We are analyzing these problems JS The answer can be found when ), such as :
FSSBBIl1UgzbN7N80T=37Na97B.nWX3....
: Numbers 80 yes http The default port number of the protocol , Corresponding http request , The first place of its value is 3, Express 3 Dari number ;FSSBBIl1UgzbN7N443T=4a.tr1kEXk.....
: Numbers 443 yes https The default port number of the protocol , Corresponding https request , The first place of its value is 4, Express 4 Dari number .
Rayleigh number 5 There are also generations with T and S The two at the end Cookie, But there's something special 5 Dai Rui number also has O and P At the end of the , alike , With O The beginning is the first 412 That request returned , With P The beginning is by JS Generated ,Cookie The first number of the value is also the version of Rayleigh number , and 3、4 The difference between generations is ,5 I didn't add the port number , such as :
vsKWUwn3HsfIO=57C6DwDUXS.....
: With O ending , The first place of its value is 5, Express 5 Dari number ;WvY7XhIMu0fGT=53.9fybty......
: With T ending , The first place of its value is 5, Express 5 Dari number .
5、 Look at the entrance , Ruishu has a process in the virtual machine VM Load in 1w+ Lines of code , The entry to load this code , Different versions are also different ( Where exactly is this entrance ? How to locate ? It will be introduced in detail in the subsequent reverse analysis ), Examples are as follows :
3 generation :
_$aW = _$c6[_$l6()](_$wc, _$mo);
,_$c6
It's actuallyeval
,_$l6()
It's actuallycall
;
4 generation :
ret = _$DG.call(_$6a, _$YK);
,_$DG
It's actuallyeval
, There are keywordsret
,call
It's plain text ;
5 generation :5 There are many kinds of generations , Initially and 4 Generation is similar , such as
ret = _$Yg.call(_$kc, _$mH);
, There are keywords ret,call It's plain text , There is no ret The version of the keyword , such as_$ap = _$j5.call(_$_T, _$gp);
, Also like 3 Generation is all confused , such as :_$x8 = _$mP[_$nU[15]](_$z3, _$Ec);
,_$mP
It's actuallyeval
,_$nU[15]
It's actuallycall
, confusedcall
And 3 The difference between generations is 5 Generation is obtained by taking values in an array ;
Of course, to accurately distinguish different versions , All conditions must be combined , The most important thing is to look at the internal implementation logic , And the code structure of the page , such as 4 Generation has a generation false Cookie Steps for , and 5 No generation , Although some special versions seem to be 5 generation , But added jsvmp And trinocular expression , And traditional 5 There are differences between generations , Occasionally, there is a new version of April Fool's day , It will be different , After analyzing each version , It's easy to distinguish .
Cookie Entrance positioning
Swiss number in this case 4 The proxy website is :aHR0cDovL3d3dy5mYW5nZGkuY29tLmNuL25ld19ob3VzZS9uZXdfaG91c2VfZGV0YWlsLmh0bWw=
First of all, go beyond infinity debugger( But it doesn't matter , In the later analysis, this basically has no effect ), Right click directly Never pause here
Never disconnect here :
location Cookie, The preferred Hook The fastest to come , adopt Fiddler Wait for bag grabbing tools 、 Oil monkey script 、 Browser plug-ins and other ways to inject the following Hook Code :
(function() {
// Rigorous model Check all errors
'use strict';
// document For hook The object of Here is hook Of cookie
var cookieTemp = "";
Object.defineProperty(document, 'cookie', {
// hook set Method is the method of assignment
set: function(val) {
// In this way, you can quickly break the following code line
// So as to quickly locate the settings cookie Code for
console.log('Hook Capture to cookie Set up ->', val);
debugger;
cookieTemp = val;
return val;
},
// hook get Method, that is, the method of value
get: function()
{
return cookieTemp;
}
});
})();
Hook It is found that there will be two generation Cookie The situation of , After disconnection, follow the stack up , You can see the assembly Cookie Code for , Similar to the following structure :
Observe these two times carefully Cookie Generated place , Follow the stack up separately , You will find two Cookie They are obtained through two different methods , As shown in the figure below :
The code here exists in VM In the virtual machine , And is IIFE Self executing code , We have to follow the stack to see these VM Where is the code loaded , Follow the stack to the home page (202 page ) with call The location of :
This is the position we introduced at the beginning of the article , This position is usually used as an entry when analyzing the Rayleigh number , In the figure _$te
It's actually eval Method , The first parameter passed in _$fY
yes Window object , The second object _$F8
It's what we saw earlier VM In the virtual machine IIFE Self executing code .
After knowing the approximate entrance of Rui number , We can also use Script The breakpoint , Go to the next breakpoint (F8) You can walk to 202 page , And then the search call Keywords can quickly locate the entry ,Script Two options in the breakpoint , The first one means running JS The first statement of the script breaks , The second means JS Cut off when blocked due to content security policy , Usually choose the first one , As shown in the figure below :
File structure and logic
Want follow-up analysis Cookie Generation , We have to observe 202 Page code ,meta The label has a content Content , A reference similar to c.FxJzG50F.dfe1675.js
Of JS file , Then follow a self executing JS, As shown in the figure below :
The first 1 part meta Labeled content Content , It changes every time , The first 2 Part of the referenced external JS There are also differences on different pages , But the same website, the same page JS The content in is usually fixed and will not change , The first 3 Part of the self executing code changes only the variable name each time , Global logic invariance , Later, when we deduct the code , Some of the methods here will also be used . There are also many self executing codes if-else
control flow , The first array , Like the one above _$Dk
It is used to control the subsequent control flow .
Refer to the c.FxJzG50F.dfe1675.js
It's garbled when you open it directly , And self execution JS The main function of is to make this JS The garbled code is restored to VM Inside 1w+ Normal code of line , And define a global variable window.$_ts
And assigned many values , This variable follows VM It plays a very important role ,meta Labeled content The content will also be in VM Used in .
Because of many values 、 Variables are dynamic , Certainly not conducive to our analysis , So we need to fix a set of code to the local , Breaking point 、 It will be more convenient to follow the stack , Keep a random copy 202 Page code , And the corresponding outer chain of this page JS file , Such as c.FxJzG50F.dfe1675.js
To local , Use the browser's own overrides Rewriting function 、 Or browser plug-ins ReRes、 Or the response replacement function of the packet capturing tool ( Such as Fiddler Of AutoResponder) Replace .
VM The code inside is generated Cookie The main code of , Contains many if-else
control flow , Undoubtedly, it increases the cost of analyzing the code , You can use AST Technology to do some anti confusion , such as Nanda will if-else
The control flow is transformed into switch-case
Of , The code under the same control flow is placed in the same case
Next , And then in call
The place at the entrance , take VM Make a local replacement of the code , For details, please refer to Nanda The article :《 A certain number 4 Generation logic analysis 》, You can try what you are interested in , Don't understand AST You can see the previous articles 《 Reverse progression , utilize AST Technical restoration JavaScript Obfuscated code 》, Time for follow-up K Brother, write again AST The actual battle of restoring Swiss number code , In this article, we choose rigid !
VM Code and $_ts Variable acquisition
We learned about VM Code and $_ts
Importance , So our first step is to find a way to get them , As for when it will be useful , Later in the article , Copy the outer chain JS, namely c.FxJzG50F.dfe1675.js
The code and 202 Page self executing code to file , Just run it locally , The environment needs to be slightly supplemented , Lack of Han make up what , Make up roughly window、location、document That's it , The specific content of the supplement can be directly used in the browser console copy()
Copy the command , then VM Code, we can directly Hook eval The way to get , The approximate supplementary environment code is as follows :
var eval_js = ""
window = {
$_ts:{},
eval:function (data) {
eval_js = data
}
}
location = {
"ancestorOrigins": {},
"href": "http://www. Desensitization treatment .com.cn/new_house/new_house_detail.html",
"origin": "http://www. Desensitization treatment .com.cn",
"protocol": "http:",
"host": "www. Desensitization treatment .com.cn",
"hostname": "www. Desensitization treatment .com.cn",
"port": "",
"pathname": "/new_house/new_house_detail.html",
"search": "",
"hash": ""
}
document = {
"scripts": ["script", "script"]
}
Observe $_ts
Of key and value, It's the same as what you get in the browser :
matters needing attention :c.FxJzG50F.dfe1675.js
Outside the chain JS If you download it directly and open it with an editor, it may be automatically encoded , It is different from the original data , This will cause an error in operation , It is recommended to access this file online directly in the browser , Copy it manually , Or copy the response content in the packet capturing software , Observe the following two situations , The first situation may lead to running errors , The second is normal :
Deduction code
So much for that , Now we can finally enter the theme , That is the deduction code , Find a good chair , Ready to put your ass on , At this time, your keyboard only F11 Useful , Continuous single step debugging , Only a hundred million details are needed , It's over !
There are too many code steps , It's impossible to write screenshots at every step , Just write something important , If there is anything missing , There's no way , First, let's replace 202 In the page , Manually add... From the beginning of code execution debugger, As soon as you enter the page, it will be disconnected , Facilitate subsequent analysis :
Through our previous analysis , I already know the entrance is call The place of , Quickly search and place breakpoints :
Through our previous analysis , We also know that there are two generation Cookie The place of , Quick search (5)
, The second search result is the entry :
false Cookie Generative logic
First of all, one step with fake Cookie, Although it's fake , But subsequent life comes true Cookie Will be used in , When you follow, you will come to this logic :
One step will call _$8e()
Method , and _$8e = _$Q9
,_$Q9
Nested in _$d0
Inside , Search where to call _$d0
, Discovery is the beginning of the code :
So the parameter passed in _$Wn
What is? ? Step into , It's a method , The function is to take 202 Page content Content , Then we will delete this locally _$Wn
Method , Direct in content The value of the can , As shown in the figure below :
in addition , We found that , The code has a lot of cases of taking values by index in the array , Like the one above _$PV[68]
Value , It's actually a string content, Obviously, we need to find the source of this array , Search directly _$PV =
, You can find the suspected definition and assignment :
So we have to look at this _$iL
Method , A very long string was passed in , Break in and have a look , Sure enough _$PV
, It's a 725 Bit array :
Next, in the process of deducting the code , You will often encounter a variable , In this article is _$sX
:
Are you familiar with ? This value is what we got earlier $_ts
Variable , You can see at the beginning that it will window.$_ts
Assigned to _$sX
:
Continue to go , Will go to the following logic :
Here we will encounter six arrays , They are already worth it , So we have to find out where they came from , Search any one of the array names , You will find the place of definition and assignment :
Assignment obviously calls _$rv
Method , Search again _$rv
Method , It is found that :
There is nothing special in the follow-up , Always single step , The last one join('')
operation , A false is generated Cookie:
FSSBBIl1UgzbN7N80T
, And then Cookie Assign a value to document.cookie
, And then to localStorage
Inside $_ck
Assigned a value , localStorage
The content of can be copied directly , It doesn't have a big impact . really Cookie Generative logic
One step with truth Cookie, In this paper, that is _$ZN(768, 1);
, You can see the beginning of endless if-else
control flow :
How should we deal with it locally ? My approach is to _$Hn
And its value name function ,function _$Hn768(){}
It means that all go 768 No. 1 control flow method , Keep following , Generating truth Cookie The method is basically 747 No. control flow , In the follow-up, we mainly focus on 747 From the various steps of the control flow ,747 The code deducted from the No. 1 control flow is roughly as follows :
Take false Cookie
One step heel 747 No. control flow , There will be an entry 709 No. 1 control flow steps , Will take the previously generated false Cookie, After a series of operations, an array is returned :
So far, we have synchronized the code of the buckle locally , If it's normal , The returned array should be the same ( The subsequent data is different , There are some parameters such as timestamp involved in the operation ):
Automated tool detection
Keep following 747 No. control flow , Will enter 268 No. control flow , Then enter the 154 No. control flow , There will be some tests for automated tools , As shown in the figure below :
Here we define a variable _$iL
, If the test fails, it means 1, Then I assigned this variable to _$aW
, So we are consistent locally , Also for the false that will do ( In fact, if we don't use automated tools , This detection does not need to be returned directly false Just go ):
20 Bit core array
Keep following 268 No. control flow , Will enter 668 No. control flow ,668 There are only two operations in the No. 1 control flow , One is to generate a 16 Digit group , Second, take $_ts
Inside 4 A variable , Add to the front 16 Bit back , Form a 20 Digit group , this 20 The last of the digit group 4 Bit is the core of Rayleigh number , The mapping relationship is wrong, and the request cannot pass , In the five generations, the processing logic of this part will be more complex .
This is not simply taking $_ts
The key value in the , When you deduct the code , You may find out how to get values here locally , What is taken out is not a number , It's a string ? It's like this :
In fact, what we first got $_ts
value , It has been processed twice , We take the first _$sX._$Xb
For example , Search directly _$sX._$Xb
, You can find such a place :
Obviously, here is _$sX._$Xb
Re assigned again , We can see to the right of the equal sign , I took it first _$sX._$Xb
, Its value is _$Rm
, This is different from our initial $_ts
The corresponding values are the same , Then we have to look again _$sX["_$Rm"]
What is sacred , Direct search finds a method assigned at the beginning , Generate new values by calling this method :
The other three values are the same routine , The assigned codes are :
_$sX._$Xb = _$sX[_$sX._$Xb](_$BH, _$DP);
_$sX._$oI = _$sX[_$sX._$oI](_$ZJ, _$DS)
_$sX._$EN = _$sX[_$sX._$EN]();
_$sX._$D9 = _$sX[_$sX._$D9](_$iL);
It should actually be :
_$sX._$Xb = _$sX["_$Rm"](_$BH, _$DP);
_$sX._$oI = _$sX["_$Nw"](_$ZJ, _$DS)
_$sX._$EN = _$sX["_$Uh"]();
_$sX._$D9 = _$sX["_$ci"](_$iL);
Further on , It's actually :
_$sX._$Xb = _$1k(_$BH, _$DP);
_$sX._$oI = _$jH(_$ZJ, _$DS)
_$sX._$EN = _$9M();
_$sX._$D9 = _$oL(_$iL);
Static analysis is ok , We can fix it first , But in practical application, these values are dynamic , So what should we do ? First, let's look at a few more and compare them to find the rules :
You can find that the corresponding order is different every time , But in fact, the method of clicking in the same position is the same , in other words , Only the method name and variable name are changed , The logic of implementation is unchanged , So we only need to know the corresponding positions of these four values , You can get the correct value , In the local , We can do that :
1、 First, use regular matching to find these four values , Such as :[_$sX._$Xb, _$sX._$oI, _$sX._$EN, _$sX._$D9]
;
2、 Then match VM At the beginning of the code 20 An assignment statement , Such as :_$sX._$RH = _$wI; _$sX._$i5 = _$n5;
etc. ;
3、 And then through $_ts
Take the value corresponding to these four values , amount to :_$sX._$Xb = _$ts._$Xb = _$Rm
; Then find the method defined by these four values in 20 Position in an assignment statement , amount to : lookup _$sX._$Rm = _$1k;
stay 20 The position in the assignment statement is 7( Index from 0 Start )
4、 We know that these four methods are 20 Position in an assignment statement , Then we directly match the name of the local corresponding location , Dynamic replacement is enough , Of course, the premise is that we have deducted a set of codes locally :
After this treatment , The accuracy of these four values can be guaranteed .
Other uses $_ts Where it's worth it
Other than that 20 In the digit group 4 individual $_ts
Beyond the value of , There are other places 7 Values are also used , Direct search can locate , this 7 Values are relatively simple , Every time it is fixed $_ts
The inside number 2、3、4、15、16、17、19 The value of a , alike , Find the location , Dynamic replacement is enough :
matters needing attention
Particular attention VM The beginning of the code , Will directly call and execute some methods , The values of some variables are generated by these methods , When you follow step by step, you find that some parameters are wrong , Or not , Then you have to pay attention to these methods at the beginning , It may have been generated from the beginning .
suffix MmEwMD Generative logic
Other follow-up XHR In request , With a suffix , The value of this suffix is also determined by JS Generated , It changes every time , Of course, different websites , The suffixes are not always the same , In this case, it is MmEwMD
, Next XHR The breakpoint , When XHR The request contains MmEwMD=
Cut off when , Then refresh the page :
You can see it and then pass it in l.open()
Of URL It's still normal , When it is disconnected, it will arrive l.send()
It has a suffix , Look again l.open()
In fact, that is xhr.open()
, Obviously different from normal , This method is also used VM In the code , It should be rewriting the method , It can be compared with normal :
Follow me VM Look in the code , After _$sd(arguments[1])
Method becomes a complete link with suffix :
To follow up _$sd
Method , The front is right url Do something about it , There is an entry at the back 779 No. 1 control flow , In fact, we generated Cookie Steps for , Just follow me .
Make good use of Watch Tracking function
Developer Tools Watch The function can continuously track the value of a variable , There are many cases of this control flow , Set the corresponding variable tracking , It can let you know which control flow you are in now , And the changes of the generated array , I don't know where to go .
The results verify that
If the whole process is ok , The code is also correct , Carry the right Cookie And the correct suffix , You can successfully visit :
End
Cui Qingcai's new book 《Python3 Web crawler development practice ( The second edition )》 It's officially on the market ! The book details the use of zero basis Python Develop all aspects of reptile knowledge , At the same time, compared with the first edition, it has added JavaScript reverse 、Android reverse 、 Asynchronous crawler 、 Deep learning 、Kubernetes Related content , At the same time, this book has obtained Python The father of Guido The recommendation of , At present, this book is on sale at a 20% discount !
Content introduction :《Python3 Web crawler development practice ( The second edition )》 Content introduction
Scan purchase
You'd better watch it
边栏推荐
- MySQL中正则表达式(REGEXP)使用详解
- Bipartite graph determination
- Method of canceling automatic watermarking of uploaded pictures by CSDN
- asp读取oracle数据库问题
- Pytest unit test series [v1.0.0] [pytest execute unittest test case]
- Detailed explanation of regular expression (regexp) in MySQL
- mysql拆分字符串作为查询条件的示例代码
- Cloud native (32) | kubernetes introduction to platform storage system
- Redis persistence mechanism
- TDengine 社区问题双周精选 | 第二期
猜你喜欢
UE4 blueprint learning chapter (IV) -- process control forloop and whileloop
JS addition, deletion, modification and query of JSON array
同构+跨端,懂得小程序+kbone+finclip就够了!
Up to 5million per person per year! Choose people instead of projects, focus on basic scientific research, and scientists dominate the "new cornerstone" funded by Tencent to start the application
Case recommendation: An Qing works with partners to ensure that the "smart court" is more efficient
NFTScan 开发者平台推出 Pro API 商业化服务
DockerMySQL无法被宿主机访问的问题解决
dockermysql修改root账号密码并赋予权限
【全网首发】Redis系列3:高可用之主从架构的
(1) Chang'an chain learning notes - start Chang'an chain
随机推荐
Let me ask you if there are any documents or cases of flynk SQL generation jobs. I know that flynk cli can create tables and specify items
With the help of this treasure artifact, I became the whole stack
Cloud native (32) | kubernetes introduction to platform storage system
Motion capture for snake motion analysis and snake robot development
ACL 2022 | small sample ner of sequence annotation: dual tower Bert model integrating tag semantics
Gpt-3 is a peer review online when it has been submitted for its own research
The problem of ASP reading Oracle Database
案例推荐丨安擎携手伙伴,保障“智慧法院”更加高效
Bipartite graph determination
安全保护能力是什么意思?等保不同级别保护能力分别是怎样?
同一个作业有两个source,同一链接不同数据库账号,为何第二个链接查出来的数据库列表是第一个账号的
What does security capability mean? What are the protection capabilities of different levels of ISO?
dockermysql修改root账号密码并赋予权限
What can be done for traffic safety?
Nftscan Developer Platform launches Pro API commercial services
docker启动mysql及-eMYSQL_ROOT_PASSWORD=my-secret-pw问题解决
Les entreprises ne veulent pas remplacer un système vieux de dix ans
Where does this "judge the operation type according to the op value and assemble SQL by yourself" mean? It means simply using Flink tab
Devsecops software R & D security practice - release
Word2vec (skip gram and cbow) - pytorch