Disclaimers
The technology mentioned in this article is only for learning purposes. It is prohibited to use any technology in this article to launch network attacks, illegal utilization and other network crimes, and all information is prohibited to be used for any illegal purpose. If the reader uses the technology mentioned in the article to commit illegal and criminal acts, the responsibility shall be borne by the reader, which has nothing to do with the author.
0x01 Preface
This paper studies the sign signature process at the HTML5 end of flying pig travel, and carries out the research on the sign signature of the API interface at the H5 end of flying pig by means of re engraving the sign signature process, aiming at querying the hotel price, and aiming at learning the technical points, ideas and how to prevent.
0x02 find a breakthrough
Capture target API request packet
Use the browser F12 developer tool to open the device simulator mode and access Hotel search page , randomly search a hotel and enter the hotel details page. All the details page requests will be captured in the NetWork tab of the developer tool.
Use Ctrl+F to find the number corresponding to the price in the page and locate the requested packet.
Analysis packet Payload
Except for a string of fields of sign signature that look like md5 ciphertext but are not md5 ciphertext, other fields are easy to understand. However, if the fields other than the sign signature field are modified, the sign signature must also be changed, and the sign signature string is obtained after operation with a fixed encryption rule. Therefore, it is urgent to find the position of the sign signature and copy the function of its operation to verify the availability of the encryption function.
field | value | Blind guess meaning |
---|---|---|
type | originaljson | It should mean that the request source type is json |
api | mtop.trip.hotel.hotelDetail | Tell the server the api service to call |
v | 1.0 | API protocol version |
params | [object Object] | I don't understand. It's estimated that the whole object was passed to params when the value was passed |
ttid | 201300@travel_h5_3.1.0 | It should also be the version number of the api |
appKey | 12574478 | As the name suggests, you can view the specific uses Taobao API open document |
t | 1641821310356 | time stamp |
sign | bb6db2ea281d6422409d820d8223147 | sign signature after a series of encryption |
data(BODY) | A large string of JSON text | This is the real request data text to be transmitted |
Locate sign signature location
To find the operation function of the sign signature, you must first find the value assigned to the sign signature string. There are many methods to locate a request parameter assignment, including hook, Ctrl+Shift+F, XHR breakpoints, etc. in addition, some complex websites often need to combine these methods to find the assignment location of a parameter. In this project, you can directly use the Ctrl+Shift+F method.
Trying to solve the problem with Ctrl+Shift+F is a cost-effective thing. The premise is that you need to guess the process behind the parameter combination logic of the website js source code.
Example of this project: the sign signature parameter of URL. It can be guessed that "& sign =" "," sign = "" and "sign" are used when splicing this parameter in the js source code of the website.
!! This method is not necessarily applicable to any website. If the js source code is seriously confused and loses the original meaning of the string, you can't use this method to find it (if there are projects in the future, you can demonstrate other search methods)
Now, try to use the global search "sign =" string to locate the code statement of suspicious sign signature assignment immediately.
You can see that there are three js files suspected of assigning value to the sign signature. At this time, you need to guess which source code should be used to assign and encrypt the sign signature according to reverse experience. However, if there is no judgment of reverse experience, you can also break the suspicious code segments of the three js files searched at the same time, view and analyze them one by one.
In fact, you can view the Request call stack in the Initiator in the request item of the Network tab. The JS file that appears most often is the JS file executed by the request encryption. Here, the most frequent occurrence is the seed-min.js file. We lock it and break the code segment.
Make a breakpoint in line 8548, refresh the page, and let the front end re request a packet and intercept it.
0x03 search for encryption entry
After the breakpoint is captured, in the sources tab, view the Scope (local variable) and CallStack (call stack) after the breakpoint, and follow the two information to the entrance of the encryption function.
Obviously, the variable e here is the sign signature string we are looking for, so we start from here and find the place of the encryption entry.
Analysis method y(i.data, m, S.a, v)
In the following code segment, it is obvious that the variable e is obtained after the operation of method y(i.data, m, S.a, v), so we have to enter the function of Y.
y(i.data, m, S.a, v).then((function(e) { d.push("sign=" + e), n({ originPath: f, search: d }) }))
Place the cursor on the method name to display the location of the method. Click to enter the definition location of the corresponding method.
There are still several methods worth checking in method y(e, t, n, r)_ (n) , method D ([n, t, R, e]. Join ("&") and variable n
Analytical method_ (n)
Obviously, this method is used to get the information in cookies_ m_h5_tk, and execute method v(n), will_ m_ h5_ The value of TK is underlined "" Split, take the left part.
Analysis method D ([n, t, R, e]. Join ("&")
View the values of the following four variables through the breakpoint at method D ([n, t, R, e]. Join ("&").
Parameter name | value | explain |
---|---|---|
n | af5ea7aa071afc99d96745743d3634d0 | _ m_ h5_ Left side of TK value |
t | 1641959319288 | time stamp |
r | 12574478 | appKey |
e | {"_fli_newpage":"1","hid":"0","adultNum":2,"shid":1002342 ...... | Request data text to be transmitted |
use. Join ("&") connects the values of four variables with "&" and passes them to method d()
Enter the method d() using single step execution, and find that its parameter variable is e, and its content is:
"af5ea7aa071afc99d96745743d3634d0&1641959319288&12574478&{"_fli_newpage":"1","hid":"0","adultNum":2,"shid":1002342 ....
Due to the space problem, the values of variable e are not expanded to view, but it can be found that the four values in the above table are spliced with "&".
// Internal of method (d) d = (r = function(e, t) { return e << t | e >>> 32 - t } , i = function(e, t) { var n, r, i, o, a; return i = 2147483648 & e, o = 2147483648 & t, a = (1073741823 & e) + (1073741823 & t), (n = 1073741824 & e) & (r = 1073741824 & t) ? 2147483648 ^ a ^ i ^ o : n | r ? 1073741824 & a ? 3221225472 ^ a ^ i ^ o : 1073741824 ^ a ^ i ^ o : a ^ i ^ o } , o = function(e, t, n, o, a, s, c) { return e = i(e, i(i(function(e, t, n) { return e & t | ~e & n }(t, n, o), a), c)), i(r(e, s), t) } , a = function(e, t, n, o, a, s, c) { return e = i(e, i(i(function(e, t, n) { return e & n | t & ~n }(t, n, o), a), c)), i(r(e, s), t) } , s = function(e, t, n, o, a, s, c) { return e = i(e, i(i(function(e, t, n) { return e ^ t ^ n }(t, n, o), a), c)), i(r(e, s), t) } , c = function(e, t, n, o, a, s, c) { return e = i(e, i(i(function(e, t, n) { return t ^ (e | ~n) }(t, n, o), a), c)), i(r(e, s), t) } , u = function(e) { var t, n = "", r = ""; for (t = 0; t <= 3; t++) n += (r = "0" + (e >>> 8 * t & 255).toString(16)).substr(r.length - 2, 2); return n } , function(e) { var t, n, r, l, p, f, d, h, g, m; for (e = function(e) { e = e.replace(/\r\n/g, "\n"); for (var t = "", n = 0; n < e.length; n++) { var r = e.charCodeAt(n); r < 128 ? t += String.fromCharCode(r) : r > 127 && r < 2048 ? (t += String.fromCharCode(r >> 6 | 192), t += String.fromCharCode(63 & r | 128)) : (t += String.fromCharCode(r >> 12 | 224), t += String.fromCharCode(r >> 6 & 63 | 128), t += String.fromCharCode(63 & r | 128)) } return t }(e), t = function(e) { for (var t, n = e.length, r = n + 8, i = 16 * ((r - r % 64) / 64 + 1), o = new Array(i - 1), a = 0, s = 0; s < n; ) a = s % 4 * 8, o[t = (s - s % 4) / 4] = o[t] | e.charCodeAt(s) << a, s++; return a = s % 4 * 8, o[t = (s - s % 4) / 4] = o[t] | 128 << a, o[i - 2] = n << 3, o[i - 1] = n >>> 29, o }(e), d = 1732584193, h = 4023233417, g = 2562383102, m = 271733878, n = 0; n < t.length; n += 16) r = d, l = h, p = g, f = m, d = o(d, h, g, m, t[n + 0], 7, 3614090360), m = o(m, d, h, g, t[n + 1], 12, 3905402710), g = o(g, m, d, h, t[n + 2], 17, 606105819), h = o(h, g, m, d, t[n + 3], 22, 3250441966), d = o(d, h, g, m, t[n + 4], 7, 4118548399), m = o(m, d, h, g, t[n + 5], 12, 1200080426), g = o(g, m, d, h, t[n + 6], 17, 2821735955), h = o(h, g, m, d, t[n + 7], 22, 4249261313), d = o(d, h, g, m, t[n + 8], 7, 1770035416), m = o(m, d, h, g, t[n + 9], 12, 2336552879), g = o(g, m, d, h, t[n + 10], 17, 4294925233), h = o(h, g, m, d, t[n + 11], 22, 2304563134), d = o(d, h, g, m, t[n + 12], 7, 1804603682), m = o(m, d, h, g, t[n + 13], 12, 4254626195), g = o(g, m, d, h, t[n + 14], 17, 2792965006), h = o(h, g, m, d, t[n + 15], 22, 1236535329), d = a(d, h, g, m, t[n + 1], 5, 4129170786), m = a(m, d, h, g, t[n + 6], 9, 3225465664), g = a(g, m, d, h, t[n + 11], 14, 643717713), h = a(h, g, m, d, t[n + 0], 20, 3921069994), d = a(d, h, g, m, t[n + 5], 5, 3593408605), m = a(m, d, h, g, t[n + 10], 9, 38016083), g = a(g, m, d, h, t[n + 15], 14, 3634488961), h = a(h, g, m, d, t[n + 4], 20, 3889429448), d = a(d, h, g, m, t[n + 9], 5, 568446438), m = a(m, d, h, g, t[n + 14], 9, 3275163606), g = a(g, m, d, h, t[n + 3], 14, 4107603335), h = a(h, g, m, d, t[n + 8], 20, 1163531501), d = a(d, h, g, m, t[n + 13], 5, 2850285829), m = a(m, d, h, g, t[n + 2], 9, 4243563512), g = a(g, m, d, h, t[n + 7], 14, 1735328473), h = a(h, g, m, d, t[n + 12], 20, 2368359562), d = s(d, h, g, m, t[n + 5], 4, 4294588738), m = s(m, d, h, g, t[n + 8], 11, 2272392833), g = s(g, m, d, h, t[n + 11], 16, 1839030562), h = s(h, g, m, d, t[n + 14], 23, 4259657740), d = s(d, h, g, m, t[n + 1], 4, 2763975236), m = s(m, d, h, g, t[n + 4], 11, 1272893353), g = s(g, m, d, h, t[n + 7], 16, 4139469664), h = s(h, g, m, d, t[n + 10], 23, 3200236656), d = s(d, h, g, m, t[n + 13], 4, 681279174), m = s(m, d, h, g, t[n + 0], 11, 3936430074), g = s(g, m, d, h, t[n + 3], 16, 3572445317), h = s(h, g, m, d, t[n + 6], 23, 76029189), d = s(d, h, g, m, t[n + 9], 4, 3654602809), m = s(m, d, h, g, t[n + 12], 11, 3873151461), g = s(g, m, d, h, t[n + 15], 16, 530742520), h = s(h, g, m, d, t[n + 2], 23, 3299628645), d = c(d, h, g, m, t[n + 0], 6, 4096336452), m = c(m, d, h, g, t[n + 7], 10, 1126891415), g = c(g, m, d, h, t[n + 14], 15, 2878612391), h = c(h, g, m, d, t[n + 5], 21, 4237533241), d = c(d, h, g, m, t[n + 12], 6, 1700485571), m = c(m, d, h, g, t[n + 3], 10, 2399980690), g = c(g, m, d, h, t[n + 10], 15, 4293915773), h = c(h, g, m, d, t[n + 1], 21, 2240044497), d = c(d, h, g, m, t[n + 8], 6, 1873313359), m = c(m, d, h, g, t[n + 15], 10, 4264355552), g = c(g, m, d, h, t[n + 6], 15, 2734768916), h = c(h, g, m, d, t[n + 13], 21, 1309151649), d = c(d, h, g, m, t[n + 4], 6, 4149444226), m = c(m, d, h, g, t[n + 11], 10, 3174756917), g = c(g, m, d, h, t[n + 2], 15, 718787259), h = c(h, g, m, d, t[n + 9], 21, 3951481745), d = i(d, r), h = i(h, l), g = i(g, p), m = i(m, f); return (u(d) + u(h) + u(g) + u(m)).toLowerCase() })
So far, the encryption entry has been exposed, that is, method d.
0x04 verify encryption method availability
The sign signature method has been obtained. The next step, of course, is to verify whether it is available.
Add a code snippet in the Snippets Tab page on the left side of the Sources Tab, copy the sign signature method to it, save it, and transfer the four key parameters into the method, and then click Run (Ctrl+Enter).
Resend a request, and then copy the values of the four parameters actually sent by the H5 end to the user-defined parameters respectively. Check whether the sign value generated by the H5 end is consistent with the running value of the newly created code fragment. If so, it means that the sign signature function can be used.
It can be seen that the sign value generated by the H5 end of the flying pig is consistent with the sign value generated by the user, both of which are fd232f8836d8713c277215d71f43820c, indicating that the sign signature encryption function we found is correct.
0x05 some words of the author
This article describes how to use the browser F12 developer tool to locate and find an encryption function. The author strongly opposes the use of this technology for substantive crawling and other forms of utilization.
Please always remember: whoever plays with the law will inevitably die in the law.