Jump to content
  • 0

How to decode JWT token header


nok1a
 Share

Question

Hi, i would like to decode base64 string but i am encountering problem with the decoding. It looks like a JWT token. The supposed to be header appears scrambled when decoding while the payload seems to be readable text. I'm using a Lua script from the web to decode the strings. I tried putting the JWT token through a auto JWT decoder but it shows no header. Only payload and signature.

image.thumb.png.4b1bc1a20697e3aac35f3a3499d78077.png

Makes me assume that it is not a header or had several xor's.


String that needs to be fully decoded: VaLciho_OwEwXdjIHdDbsoR4KYTtYV06b9bwtdm9ceQ.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc1NjE4NzE4fQ

Payload decoded: eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc1NjE4NzE4fQ

image.thumb.png.073810e5fed96705ead32e2fc50664b7.png

Header scrambled when decoded:VaLciho_OwEwXdjIHdDbsoR4KYTtYV06b9bwtdm9ceQ

image.thumb.png.9e38bae2c491811e1766828495feaef2.png

Link to comment
Share on other sites

11 answers to this question

Recommended Posts

  • 0

Hi @nok1a, as above presence, the JWT mentioned is not a valid one. JWT Header should be in JSon Format. In your string, the JWT Header is incorrect, which can be assumed it is a payload or the footer of JWT. Not to mention that: the mentioned JWT don't have the footer. Both Payload and Header usually use the same JSon object which formatted as: ( ey (.ey (.AvBnCD ). Let's talk about it more:

[ Main Section ]

  • 1) If you switched the header position into Payload section, you'll get a glimpse of escaped Unicode character (\u001a) that wrapped in double-quotes. This may indicate something:
Quote
  • eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc1NjE4NzE4fQ.VaLciho_OwEwXdjIHdDbsoR4KYTtYV06b9bwtdm9ceQ
  • Payload: "U�܊\u001a?;\u00010]��\u001d�۲�x)��a]:o���ٽq�"
  • 2) The scrambled result maybe comes from Memory Artifact, which the Data are partially flushed from the memory but it remains there as a glimpse. Usually, Memory reserves this Data multiple times in many addresses, perhaps you need to find them that follow JWT format.
Quote
  • "Receipt":���������*���a €�Z¹¯¾Nj¯®����������������©¿Øn
  • "Receipt":"eyJhbGciOiJS..."
  • 3) The game can also Encrypt the JWT Format, partially or entire token. Which usually involve XORing of your Game Account and Session.
Quote
  • Hpe84d2/+buj5pSgc8gz2TxXjjk+2cdQHSq6shquLZskGLC...
  • "Receipt":"eyJhbGciOiJS...

[ Notes ]

Examples are taken from real schenario by comparing both situation with it's precendence case.
Paper.thumb.png.0f2f4c5d2d46c701bab2c0df394ebb00.png

Edited by MC189
Link to comment
Share on other sites

  • 0
On 2/6/2023 at 7:05 PM, MC189 said:

 

  • 1) If you switched the header position into Payload section, you'll get a glimpse of escaped Unicode character (\u001a) that wrapped in double-quotes. This may indicate something:

Done that, but have no idea about how unicode character will help me. Perhaps you can refine "This may indicate something".

On 2/6/2023 at 7:05 PM, MC189 said:

 

  • 2) The scrambled result maybe comes from Memory Artifact, which the Data are partially flushed from the memory but it remains there as a glimpse. Usually, Memory reserves this Data multiple times in many addresses, perhaps you need to find them that follow JWT format.

I'm not fully following.

I assume the client will send a authentication request to the server in which the userCookie token is complete. I don't yet understand what i need to look for in memory. This token is the way it is stored on ones device when making an account. If modified and send to server you get an error responds back saying wrong signature.

 

On 2/6/2023 at 7:05 PM, MC189 said:

 

  • 3) The game can also Encrypt the JWT Format, partially or entire token. Which usually involve XORing of your Game Account and Session.

For it to be encrypted would it still require to follow the 2+ dots? Because this one only has one. I checked the doc that CmP gave in his explanation, but then for the encryption part. but all types of JWP token talk about encryptions which at the minimum causes the token to have 2 dots in it.

Link to comment
Share on other sites

  • 0

The thing is, i am not sure what causes the wrong signature error.

I almost assuming that the scrambled part is some kind of check algorithm for the readable part. So that if there is tempering to the readable part the server will know because the algorithm and readable info are not compatible anymore. 

Just a bit like a FCS would work(i guess).

Link to comment
Share on other sites

  • 0

Hi @nok1a, I would want to know what apps that you obtain this JWT from? Hence, We can only talk about it from the surface area.
[ Answers ]

Quote

Perhaps you can refine "This may indicate something".

The thing is: it resembles encrypted data. My thought about your JWT Tokens:

  • I would highly sure it is a payload not the headers. Headers usually un-encrypted and mention the use of encryption algorithm that JWT used. See RFC7516 Section 3.3: Example JWE
  • Your JWT Token don't have JWT Tags which mention "enc" for encryption or "alg" for algorithm used, according to the same RFC (Or the Headers can also be customized?)

image.thumb.png.f8d3f89bdc95c1c5800b59503f51e42b.png

Quote

For it to be encrypted would it still require to follow the 2+ dots?

Normal JWT token is surely supports for Payload Encryption, but, the game can also do another client-side encryption to 'HIDE' the JWT Token, like I mentioned in the Previous Examples. The requirement is atleast one dot only according to RFC7519 Section 7.2: Validating JWT.

Quote

but all types of JWP token talk about encryptions which at the minimum causes the token to have 2 dots in it.

It's true, both JWS and Main JWT RFC papers seems strictly use the format of Header.Payloads.Signature as mentioned in RFC 7515 Section 3.3: Example JWS. Altho, There's no mention of such concatenation format in JWE.

Quote

Because this one only has one.

Are you getting this JWT from Memory or Packet Request or LocalCache files? To me, this seems roughly taken from Memory or Response Packet, this partially explain the missing of signature.

Quote

The thing is, i am not sure what causes the wrong signature error.

From your initial JWT Tokens, there're no sign of Signature. As expected, the server replied with such. I also left confused, I'm in the same boat as you. The problem with your token is:

  • - There're no such mention about encryption and algorithm being used, it will portray the signature being used in the JWT.
  • - It don't have signature / authentication. All types of JWT puts it's auth/sig at the end, but this token have None.
Quote

I almost assuming that the scrambled part is some kind of check algorithm for the readable part. So that if there is tempering to the readable part the server will know because the algorithm and readable info are not compatible anymore. 

Most likely, then it would be just a regular Authentication that similar to JWT (Use [.] for parsing). The indication is, it's usualy have Query Parameter in its URL (?acess_token=blah)

[ Main Section ]

Quote

Unsecured JWSs (JWSs that use the "alg" value "none") provide no integrity protection. Thus, they must only be used in contexts in which the payload is secured by means other than a digital signature or MAC value, or they need not be secured.

Taken from RFC 7518 Section 8.5: Unsecured JWS, this perhaps explain why the headers and signature are missing, the JWT Token is considered as Unsecure since both are incorrect. However, this doesn't explain 'Wrong Signature Error'.

Quote

responds back saying wrong signature.

We can assume several things:

  • - This is the correct JWT Tokens, since it's follow one dot requirement. Let's assume that this is used for POST Method bearers. Perhaps, the server replies 'Wrong Signature Error' can comes from the missing of Request Payload (Not JWT Payload). Usually, it's sends as Raw, Json, or XML format.
  • - JWT Signature are probably added Automaticly when the Requests are sent by the App, this left only chunks of JWT that are saved, if the tokens are taken from LocalCache.
  • - The Server does NOT support others type of Request Method other than POST.
  • - The Server is reserve for Proxy. This usually used in Online type of App, which can result  in '400 vip_default_vip' or '400 Bad Request'. You need to put Absolute URL as Request Path.
GET http://blah.com HTTP/1.1\r\nAuthorization: ey...


[ Notes ]
So far it's still Unclear where the Exact Problem is, we can only assume based on your mentioned JWT Tokens. Perhaps, the Token itself is Invalid from the beginning.

  • - Attach the Request that you sends to the server (Payload, Headers, URI, and some Dummy JWT)
  • - Attach the Server Response, including (Response Status Code, Response Header, and Response Content)
  • - Mention the Apps Name or the Link to it.
Edited by MC189
words
Link to comment
Share on other sites

  • 0
On 2/9/2023 at 9:31 PM, MC189 said:

Hi @nok1a, I would want to know what apps that you obtain this JWT from? Hence, We can only talk about it from the surface area.

Guns Of Boom

On 2/9/2023 at 9:31 PM, MC189 said:

Are you getting this JWT from Memory or Packet Request or LocalCache files? To me, this seems roughly taken from Memory or Response Packet, this partially explain the missing of signature.

web debugging proxy -> fiddler

Full request: http://game.www.gobmobile.com/api/auth.enter?output=amf&clientData={"deviceModel"%3A"Asus ASUS_Z01QD"%2C"connectionType"%3A"WIFI"%2C"graphicsDeviceName"%3A"Adreno (TM) 640"%2C"graphicsDeviceVersion"%3A"OpenGL ES 3.0"%2C"graphicsMemorySize"%3A1024%2C"operatingSystem"%3A"Android OS 7.1.2 %2F API-25 (N2G48H%2Frel.se.infra.20200730.150525)"%2C"processorCount"%3A4%2C"processorType"%3A"ARMv7 VFPv3 NEON VMH"%2C"systemMemorySize"%3A3546%2C"gitRevision"%3A"f227fba487d904c2e6e4d71828b5754ca355ab2a-207"%2C"version"%3A"24.1.207"%2C"deviceId"%3A"08eca84316b4153c1670a5717cdcafed"%2C"googleAdvertisingId"%3A"44c43f7e-a2ff-4333-ac7b-b221f219fb04"%2C"googleAndroidId"%3A"cd4d354f1ef238b4"%2C"piracy"%3A{"licensing"%3A"retryChecking"%2C"installerId"%3A"true"%2C"signingCertificate"%3A"true"}}&platform=android&deviceId=08eca84316b4153c1670a5717cdcafed&setCookie[account]=ZUs8TGBcN6FR7kjJrql343FfwPHRYnlobtJyxmAByB4.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTYyMzA4NTI3MX0&setCookie[user]=VaLciho_OwEwXdjIHdDbsoR4KYTtYV06b9bwtdm9ceQ.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc1NjE4NzE4fQ&resolution=hd&lang=en&returnCookies=1&seq=4

Link to comment
Share on other sites

  • 0
On 2/9/2023 at 9:31 PM, MC189 said:

- Attach the Server Response, including (Response Status Code, Response Header, and Response Content)

I don't have acess to the tools. Response. Through GG. Hope it has the needed info.

Script ended:
{ -- table(ffbb891)
	['code'] = 200,
	['content'] = '	%setCookie[account]�/DEvIPj54NwK5EI5vW8_k4iwcV6_rWDABEIvvgcXpso8.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTY3NjQ2MzMzNX0setCookie[user]�5MUbMehx_aPdSzp1LcRpEoHMRvC_Sw_XLHwEtPB98k40.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc2NDYzMzM1fQinitTimeA��39�timezoneOffset�0contentDomain/gobmobile.akamaized.netconfigs	ruYshared/as/ru/contextConfig.amf?ux=1676462708enYshared/as/en/contextConfig.amf?ux=1676462707trYshared/as/tr/contextConfig.amf?ux=1676462708frYshared/as/fr/contextConfig.amf?ux=1676462707itYshared/as/it/contextConfig.amf?ux=1676462707deYshared/as/de/contextConfig.amf?ux=1676462706esYshared/as/es/contextConfig.amf?ux=1676462707ptYshared/as/pt/contextConfig.amf?ux=1676462708pt-BR_shared/as/pt-BR/contextConfig.amf?ux=1676462708nlYshared/as/nl/contextConfig.amf?ux=1676462708koYshared/as/ko/contextConfig.amf?ux=1676462707jaYshared/as/ja/contextConfig.amf?ux=1676462707ltYshared/as/lt/contextConfig.amf?ux=1676462708zh-Hanscshared/as/zh-Hans/contextConfig.amf?ux=1676462709zh-Hantcshared/as/zh-Hant/contextConfig.amf?ux=1676462709remoteIp185.124.28.154cidUser.91060619env	mainkeyA50d53aca6c02795f355bd3284e4207c2	langlevel	nickPlayer 91060619tcp%35.246.142.97:7712seq4
status',
	['contentLength'] = -1,
	['contentType'] = 'application/octet-stream',
	['date'] = 1676463335000.0,
	['expiration'] = 869893200000.0,
	['headers'] = { -- table(18ff3f6)
		['Cache-Control'] = { -- table(e552264)
			[1] = 'no-store, no-cache, must-revalidate',
			[2] = 'post-check=0, pre-check=0',
		},
		['Connection'] = { -- table(6bf5982)
			[1] = 'keep-alive',
		},
		['Content-Transfer-Encoding'] = { -- table(8124ccd)
			[1] = 'binary',
		},
		['Content-Type'] = { -- table(c7400d0)
			[1] = 'application/octet-stream',
		},
		['Date'] = { -- table(86ae801)
			[1] = 'Wed, 15 Feb 2023 12:15:35 GMT',
		},
		['Expires'] = { -- table(ce403f7)
			[1] = 'Mon, 26 Jul 1997 05:00:00 GMT',
		},
		['Keep-Alive'] = { -- table(85719e8)
			[1] = 'timeout=20',
		},
		['Last-Modified'] = { -- table(444d70b)
			[1] = 'Wed, 15 Feb 2023 12:15:35 GMT',
		},
		['Pragma'] = { -- table(b8d8bce)
			[1] = 'no-cache',
		},
		['Server'] = { -- table(9fb46a6)
			[1] = 'nginx/1.18.0',
		},
		['Transfer-Encoding'] = { -- table(b6059fc)
			[1] = 'chunked',
		},
		['X-Android-Received-Millis'] = { -- table(b317aef)
			[1] = '1676463335138',
		},
		['X-Android-Response-Source'] = { -- table(dfa96da)
			[1] = 'NETWORK 200',
		},
		['X-Android-Selected-Protocol'] = { -- table(683e8c9)
			[1] = 'http/1.1',
		},
		['X-Android-Sent-Millis'] = { -- table(94ae893)
			[1] = '1676463335010',
		},
		['null'] = { -- table(8594885)
			[1] = 'HTTP/1.1 200 OK',
		},
	},
	['lastModified'] = 1676463335000.0,
	['message'] = 'OK',
	['requestMethod'] = 'GET',
	['url'] = 'http://game.www.gobmobile.com/api/auth.enter?output=amf&clientData={"deviceModel"%3A"Asus ASUS_Z01QD"%2C"connectionType"%3A"WIFI"%2C"graphicsDeviceName"%3A"Adreno (TM) 640"%2C"graphicsDeviceVersion"%3A"OpenGL ES 3.0"%2C"graphicsMemorySize"%3A1024%2C"operatingSystem"%3A"Android OS 7.1.2 %2F API-25 (N2G48H%2Frel.se.infra.20200730.150525)"%2C"processorCount"%3A4%2C"processorType"%3A"ARMv7 VFPv3 NEON VMH"%2C"systemMemorySize"%3A3546%2C"gitRevision"%3A"f227fba487d904c2e6e4d71828b5754ca355ab2a-207"%2C"version"%3A"24.1.207"%2C"deviceId"%3A"08eca84316b4153c1670a5717cdcafed"%2C"googleAdvertisingId"%3A"44c43f7e-a2ff-4333-ac7b-b221f219fb04"%2C"googleAndroidId"%3A"cd4d354f1ef238b4"%2C"piracy"%3A{"licensing"%3A"retryChecking"%2C"installerId"%3A"true"%2C"signingCertificate"%3A"true"}}&platform=android&deviceId=08eca84316b4153c1670a5717cdcafed&setCookie[account]=ZUs8TGBcN6FR7kjJrql343FfwPHRYnlobtJyxmAByB4.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTYyMzA4NTI3MX0&setCookie[user]=VaLciho_OwEwXdjIHdDbsoR4KYTtYV06b9bwtdm9ceQ.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc1NjE4NzE4fQ&resolution=hd&lang=en&returnCookies=1&seq=4',
	['usingProxy'] = false,
}

 

Link to comment
Share on other sites

  • 0

Hi @nok1a, I'm not yet touching the Game since I dont really have the time for it, but, I have experimenting with the API above and I will give my thoughts to it.

[ Response

Quote

%setCookie[account]ƒ/dPPOtrBg_ud_Ia10nz_SPTrIP4jcq4VMo1w51OiaIWY.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTY3NjQ5MjQzMH0setCookie[user]5qX-EcJ1RKwN_Cki9t3Yrftj3T6CmfGscME1SbLRoVpc.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc2NDkyNDMwfQinitTimeAØûO£€  timezoneOffsetÔ0contentDomain/gobmobile.akamaized.netconfigs    ruYshared/as/ru/contextConfig.amf?ux=1676491510enYshared/as/en/contextConfig.amf?ux=1676491508trYshared/as/tr/contextConfig.amf?ux=1676491510frYshared/as/fr/contextConfig.amf?ux=1676491508itYshared/as/it/contextConfig.amf?ux=1676491508deYshared/as/de/contextConfig.amf?ux=1676491508esYshared/as/es/contextConfig.amf?ux=1676491508ptYshared/as/pt/contextConfig.amf?ux=1676491509pt-BR_shared/as/pt-BR/contextConfig.amf?ux=1676491509nlYshared/as/nl/contextConfig.amf?ux=1676491509koYshared/as/ko/contextConfig.amf?ux=1676491509jaYshared/as/ja/contextConfig.amf?ux=1676491509ltYshared/as/lt/contextConfig.amf?ux=1676491509zh-Hanscshared/as/zh-Hans/contextConfig.amf?ux=1676491510zh-Hantcshared/as/zh-Hant/contextConfig.amf?ux=1676491510remoteIp180.241.243.177cidUser.91060619env    mainkeyA8489ae90046f42608128f5668e91999c    langlevel    nickPlayer 91060619tcp%35.246.142.97:7710seq4
status

Your Initial API response differently each time you make Request. The response contains some interesting things that I will talk about it in this section.

Quote

setCookie[account]: dPPOtrBg_ud_Ia10nz_SPTrIP4jcq4VMo1w51OiaIWY.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTY3NjQ5MjQzMH0
{
  "id": 51949654,
  "email": "[email protected]",
  "socialNetworks": {
    "ga": "116115244384107732953"
  },
  "ctime": 1676492430
}
5qX-EcJ1RKwN_Cki9t3Yrftj3T6CmfGscME1SbLRoVpc.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc2NDkyNDMwfQ
{
  "id": 91060619,
  "ctime": 1676492430
}

As you can see, it's generating a new setCookie token. Even tho it's generating a new one, the initial Token that made the Request is still Valid. This lead me to assume that this is a Token Dispenser.

Quote

key A8489ae90046f42608128f5668e91999c

The response also contains some key, which likely to prove that this is a Token Dispenser. I don't know which one that are used by the game, is it the key or the new generated cookies.

Quote

Response:
gobmobile.akamaized.net
shared/as/en/contextConfig.amf?ux=1676491508

Parameter:
lang: en
resolution: hd

User-Info:
nick: Player 91060619
level:

 

A User-Info? Hmm, interesting. Judging from the Response, it is likely that you can somehow increase the Level just only sending data into the API. I assume that this request Response will later be used by the game to Access other API Link, Download Configs, etc.

Quote

    resources        prod        pathsshared/resources/prod/Android/manifest.json?ux=1653410236    size����md5A15d6456b81fb25ab1390cb06ce5a8340prod-community    ushared/resources/prod-community.Android.json?ux=1653411340��� 
A98f2ddc92e0926f57b9464ddd27a36bf#resourcesManifest    langenshared/as/en/files    abilities.amf    mtimeA،�@

This is the response when you're doing request to gobmobile.akamaized.net/shared/as/en/contextConfig.amf?ux=1676491508 that mentioned from the first Response. It is a config with .amf extension. Oh wait, I remember something.

Quote

The request with your JWT token also mention to save the response as .amf config. Perhaps that can be used as a Payload to access something, as binary off course. Perhaps you need to find a request that contains a Payload/Body through fidler.

[ Thoughts ]
With that being said, I assume:

  • - It is a Token Dispenser that will generate a new Token for temporarily access something. You might want to investigate this further by taking the generated Token and find if it's being used elsewhere.
  • - The Token might not be a JWT but it is only base64 encoded payload with some 'check algorithm' as you said earlier, since the generated token is having the same length as the first one.
Quote

Original:
ZUs8TGBcN6FR7kjJrql343FfwPHRYnlobtJyxmAByB4.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTYyMzA4NTI3MX0
Generated:
dPPOtrBg_ud_Ia10nz_SPTrIP4jcq4VMo1w51OiaIWY.eyJpZCI6NTE5NDk2NTQsImVtYWlsIjoiMTE2MTE1MjQ0Mzg0MTA3NzMyOTUzQGdhLmZ1bnpheS5jb20iLCJzb2NpYWxOZXR3b3JrcyI6eyJnYSI6IjExNjExNTI0NDM4NDEwNzczMjk1MyJ9LCJjdGltZSI6MTY3NjQ5MjQzMH0

  • - I also find it weird that the User Cookie has 1 different character length between the generated version and the original one.
Quote

Original:
VaLciho_OwEwXdjIHdDbsoR4KYTtYV06b9bwtdm9ceQ.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc1NjE4NzE4fQ
Generated:
5qX-EcJ1RKwN_Cki9t3Yrftj3T6CmfGscME1SbLRoVpc.eyJpZCI6OTEwNjA2MTksImN0aW1lIjoxNjc2NDkyNDMwfQ

[ Conclusion ]
I hope this provides an answer to this thread.

  • - The Config Links can be accessed directly without the need of Parameter / Authorization.
  • - setCookie[account] and setCookie[user] are both inherited each other.
  • - 'check algorithm' and base64 Payload are both inherited each other (in One setCookie)
  • - Made another request will cause the Previous generated token Invalid, a one time use or session based Token.
     
Edited by MC189
typo
Link to comment
Share on other sites

  • 0

Thanks lot for the info.

Pointing specifically to the userCookie. You can reuse the same token, It stays valid. This is a authentication request that is used to sign in to your in-game account. By changing the userCookie token you can change the account you can login to(for example).

Ok, so i understand that it comes down to a token with some check algorithm to make sure there is no tempering on the user ID and session time. So what i want is to modify that user info in the userCookie token and send to the server and have it being received as valid by the server. This can't work if i do not know the appropriate check algorithm used.

  1. I try to understand that check algorithm.
  2. Any thoughts on how the check could work.


 

Link to comment
Share on other sites

  • 0

Hi @nok1a, I think you should do Reverse Engineering since it is Unity based Game. I have take a glance look at the Game Library:

  • - There's get_cookie and set_cookie function inside the libil2cpp.so but it is assigned to Unity graphics, I don't know if its just the naming, but, you should dump it instead to see a better look.
  • - Since it's tied to Unity Graphics, I'm thinking that the get_cookie I look is for applying the Config. It is more likely that the Token is handled, parsed, and generated Server Sidedly. Thus, the Client only using the Token instead of doing anything to the Token. I might be wrong, since I don't have dump.cs.
  • There's no direct mention of setCookie inside the lib, so you might as well take a look at libjs as well because the Response roughly involve JSon format.
    configs    ruYshared/as/ru/contextConfig.amf?ux=1676491510enYshared/as/en/contextConfig.amf?ux=1676491508
    {
    "configs:{
    "ru": "shared/as/ru/contextConfig.amf?ux=1676491510",
    "en": "shared/as/en/contextConfig.amf?ux=1676491508"
    }

     

Edited by MC189
words
Link to comment
Share on other sites

  • 0
On 2/18/2023 at 11:45 AM, MC189 said:

Hi @nok1a, I think you should do Reverse Engineering since it is Unity based Game.

I only familiar with very little about "Reverse Engineering" game apk's. I also would need to know what i be looking for which i don't think i do. Or perhaps yes, but its not on client. its on server because that token is generated server sided as you said. Itried dumping but could not find anything which can help me figuring out that check algorithm.

 

On 2/18/2023 at 11:45 AM, MC189 said:

- Since it's tied to Unity Graphics, I'm thinking that the get_cookie I look is for applying the Config. It is more likely that the Token is handled, parsed, and generated Server Sidedly. Thus, the Client only using the Token instead of doing anything to the Token. I might be wrong, since I don't have dump.cs.

I also believe token generating is happening server sided and client just using it to get response from server for sign in. I tried making 2 new accounts at the same time to see if i could find some similarity on the check algorithm between both setCookie's while having a near identical user/ctime info:

VAFN4XG9Usx1pW3oo8tnMbR8E3apWJQJgMvMNAEFpXM.eyJpZCI6OTI2MDU5MzEsImN0aW1lIjoxNjc2ODM0MDE2fQ
LbuRCOPZ1mW1a34TnYJVBdG9AHJP05M88y3Iu7v7jhA.eyJpZCI6OTI2MDU5MzIsImN0aW1lIjoxNjc2ODM0MDE2fQ

So if i make changes to the token and send to server i will get a error at the validation part:

image.thumb.png.2b7157604fd17282ee93b0659c223825.png

I'm only "assuming" that the issue is with wrong checksum. It can be worst, that it also requires the right ctime, ctime of other players is something which i have not been able to find on my client with GG nor checking the packages with wireshark that are transmitted using TCP protocol.

The first part of the token is always 43 characters long. I am not sure if this reasonable but perhaps i need to make a script that kind of calculates all possible check algorithms? But i have no idea if it is still reasonable at that point. base64URL has 62 different chars, by the power of 43 it be a absurd amount of trials. I don't even think GG is build for it. Perhaps need to use something more suitable for this thing and then make the result of it compatible with GG. Dunno.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.