DEV Community

Illia Zub
Illia Zub

Posted on

Reverse Engineering Poocoin API (Part 1)


What will be scraped

image


Explanation

We want to reverse engineer URL data parameter:

# full url 
https://poocoin.app/api2/candles-bsc?data=[YmLNHK6TU[Kblm4UXqKeF2FTYSSW2KsZ32XfnO6TU[KblJ1UVeONWKGSYebblF{U2S[fWqIVYeObmVzXYqCN1:VTUCQSGmOWHiWUWSCOl6VWU[OSFG2UVSCe2eqTYOKcYixZmetNFmrc4qOblG{TX25e2GYVnukcW[7Z4mKOlmrRkSTS2FyXXuHb1:IXUS[bl1zUVeSN16uVYiOb2qsVWSKfl2GXUSSb1[IUlSLcWqVRYeOblqFVnmKd1mucIWlS2[6[H2Hd1mrc3mOWG[1TXm4bWmuSoqbWYi4TXqwbV2J[{GQSWl1Uoq[OF6V[HiOSFqGUnqkNl2sWYeOWFG5XX2KNWG7VUKSWHirUWWXSV6FVlW[flVzTX5xQR%3E%3E

# data parameter
[YmLNHK6TU[Kblm4UXqKeF2FTYSSW2KsZ32XfnO6TU[KblJ1UVeONWKGSYebblF{U2S[fWqIVYeObmVzXYqCN1:VTUCQSGmOWHiWUWSCOl6VWU[OSFG2UVSCe2eqTYOKcYixZmetNFmrc4qOblG{TX25e2GYVnukcW[7Z4mKOlmrRkSTS2FyXXuHb1:IXUS[bl1zUVeSN16uVYiOb2qsVWSKfl2GXUSSb1[IUlSLcWqVRYeOblqFVnmKd1mucIWlS2[6[H2Hd1mrc3mOWG[1TXm4bWmuSoqbWYi4TXqwbV2J[{GQSWl1Uoq[OF6V[HiOSFqGUnqkNl2sWYeOWFG5XX2KNWG7VUKSWHirUWWXSV6FVlW[flVzTX5xQR%3E%3E
Enter fullscreen mode Exit fullscreen mode
  • data parameter contains token id, time interval, date, and limit argument which I believe is for candles amount to display.

Open dev tools, find relevant XHR request and go to JS source:

image

Format JavaScript code:

image

Go up in the stack trace to see the formation of data URL argument:

image

Evaluate F, W, B I variables to understand what's happening:

image

B = w(476):

image

w() returns function name:

image

var n = ["map", "70209pSjRdP", "13mXPpTk", "32970804XTFOSy", "33EDoYDa", "16914prTfjD", "charCodeAt", "680Pigxyq", "5194335PIAMSW", "stringify", "430dfxvAD", "21ASPctV", "&l=1", "4868dULKHq", "955100otFPGh", "substring", "QWRkcmVzcyI6IjB4MGM1REEwZjA3OTYyZGQwMjU2YzA3OTI0ODY", "4483450KFkYTE", "2303RvgaFj", "lpr", "host", "indexOf"];

function w(e, t) { return n[e - 467] }
Enter fullscreen mode Exit fullscreen mode

I contains base64 encoded characters shifted by one charater code to the right:

let obfuscatedFunctionName = w(476) // B = w(476),
obfuscatedFunctionName === n[9] && obfuscatedFunctionName === "QWRkcmVzcyI6IjB4MGM1REEwZjA3OTYyZGQwMjU2YzA3OTI0ODY" // => true

let base64CharactersOfParamsBase64 = btoa("" + prefixOfEncodedParams + obfuscatedFunctionName + suffixOfEncodedParams).split("") // I = (I = (I = (I = (I = btoa("" + W + B + S)).split(""))

let base64CharactersPlusOneOfParamsBase64 = base64CharactersOfParamsBase64.map(function(e) {
  let charCodePlusOne = e.charCodeAt() + 1 // e[w(488)](0) + 1; w(488) === "charCodeAt"
  return charCodePlusOne
}).map(function(e) { // w(482) === "map"
  return String.fromCharCode(e)
}).join("")
Enter fullscreen mode Exit fullscreen mode

Which is effectively the same as:

let base64CharactersPlusOneOfParamsBase64 = base64CharactersOfParamsBase64.map(e => String.fromCharCode(e.charCodeAt() + 1)).join("")
Enter fullscreen mode Exit fullscreen mode

Example value and test

base64CharactersPlusOneOfParamsBase64 === '[YmLNHK6TU[Kblm4UXqKeF2FTYSSW2KsZ32XfnO6TU[KblJ1UVeONWKGSYebblF{U2S[fWqIVYeObmVzXYqCN1:VTUCQSGmOWHiWUWSGOl6VRU[OSFG2UVSCe2eqTYOKcYixZmetNFmrc4qOblG{TX25e2GYVnukcW[7Z4mKOlmrRkSOWGKFUmSsNF2rTYmOWFFzUXqofmqIVUKTSFVyUmeKOWqFRYe[WHtxUUKKOV6FSUGOflFzUnmKd1mucIWlS2[6[H2Hd1mrc3mOWG[1TXm4bWmuSoqbWYi4TXqwbV2J[4mPSHyrXlSCNV6FXUWPNmlxUWeSN11xXYiSWHe5Xn2Ge2KrWYmPfnyuXUKPcF1zUlePflKrTX5xQR>>' // => true
base64CharactersPlusOneOfParamsBase64 === I // => true
Enter fullscreen mode Exit fullscreen mode

Now compare it with string in request:

https://poocoin.app/api2/candles-bsc?data=[YmLNHK6TU[Kblm4UXqKeF2FTYSSW2KsZ32XfnO6TU[KblJ1UVeONWKGSYebblF{U2S[fWqIVYeObmVzXYqCN1:VTUCQSGmOWHiWUWSGOl6VRU[OSFG2UVSCe2eqTYOKcYixZmetNFmrc4qOblG{TX25e2GYVnukcW[7Z4mKOlmrRkSOWGKFUmSsNF2rTYmOWFFzUXqofmqIVUKTSFVyUmeKOWqFRYe[WHtxUUKKOV6FSUGOflFzUnmKd1mucIWlS2[6[H2Hd1mrc3mOWG[1TXm4bWmuSoqbWYi4TXqwbV2J[4mPSHyrXlSCNV6FXUWPNmlxUWeSN11xXYiSWHe5Xn2Ge2KrWYmPfnyuXUKPcF1zUlePflKrTX5xQR%3E%3E
Enter fullscreen mode Exit fullscreen mode

image


In the next part, we'll write the actual code that will construct the URL and retrieve the data.

Outro

If you have anything to share, any questions, suggestions, or something that isn't working correctly, feel free to reach out via Twitter at @ilyazub.

P.S. Thanks to @dmitryzub for help on this project and for co-authoring this article.

Top comments (0)