RCE Endeavors 😅

November 18, 2021

Reverse Engineering REST APIs: Debugging (4/12)

Filed under: Game Hacking,Programming,Reverse Engineering — admin @ 2:15 PM

Table of Contents:

The simplest way to begin reverse engineering an application is to look for hints from inside the application itself as to what it is doing. In a dynamic analysis setting, where we are going to examine a running executable, this is best done by attaching a debugger to it. From there we can begin looking at string references and see if there is anything interesting.

For example, our target goal is to find the request builder and response decryption functions in the target executable. After attaching a debugger, we can do a string dump and look for values such as “packet”, “encrypt”, “decrypt”, “message”, “response”, etc. and see if we can get any leads into where these functions might be located. We can also try to find out if they are implemented internally, or via a third-party library, and what encryption libraries are used, as well as other relevant features of the client-server communication flow.

To begin, lets attach x64dbg to the Age of Empires IV executable (RelicCardinal.exe). From the module view in the Symbols tab, we can find the main executable.

Once we are viewing the main module (via double clicking the row with reliccardinal.exe), we can take a look at the string references (right click, Search for -> Current Module -> String references).

From inspecting the network traffic previously, we know that TLS is being used to perform secure calls to the server. We can take a look for strings such as “encrypt”, “decrypt”, “tls”, and “ssl” to see if there is anything interesting. The first three searches didn’t yield anything too much, however, when looking for “ssl”, there is something notable. There is a string reference to SSLKEYLOGFILE.

SSLKEYLOGFILE is a special environment variable that can be set to log SSL key information. The contents of this file can then be used by Wireshark to decrypt the network traffic. If the game supports the use of this environment variable then it is another way to see the plaintext network traffic without having to deal with the hassle of setting up a HTTPS proxy and routing the application traffic through it. To test it is simple: create an environment variable called SSLKEYLOGFILE and set its value to a path on your filesystem. Then launch the game and see if anything is written out to the file. If you’ve done it successfully, there should be SSL key information in the file, confirming that the use of this environment variable is enabled.

Having this key information, we should be able to see decrypted data in Wireshark. To see this, we can launch Wireshark and begin monitoring. We then launch the game and perform some actions to ensure REST calls are being made. Finally, we import the SSL key information in Wireshark via Edit -> Preferences -> Protocols -> TLS and provide the SSL key file.

Once these changes are applied, we can filter out traffic to the server and verify that the decrypted application data is visible.

The decrypted requests appear to be present. We can view the full request-response flow by right clicking on a request and selecting Follow -> HTTP Stream

This quick find provided all of the insight needed to reverse engineer the REST APIs. But what if the SSLKEYLOGFILE environment variable was unsupported? We would have to dig a bit deeper into the strings dump, which we’ll do while we’re here anyway. Searching for “http” provides some interesting information:

"handle_read_http_response"
"handle_send_http_request"

These appear to be WebSocket functions. These are good to know, but probably not what we are interested in, as the client-server communication we are reverse engineering is not done via WebSockets. If these functions are used, it is probably from within a multiplayer game instance where the lower overhead full-duplex connection that WebSockets provide is a good choice.

"%s HTTP/%s\r\n%s%s%s%s%s%s%s%s%s%s%s"

This looks like a format string for an HTTP request.

"HTTP_E_STATUS_UNEXPECTED"
"HTTP_E_STATUS_UNEXPECTED_SERVER_ERROR"
"HTTP_E_STATUS_UNEXPECTED_CLIENT_ERROR"
"HTTP_E_STATUS_UNEXPECTED_REDIRECTION"
...

These are constants used by the Xbox Live Networking library.

"https://sessiondirectory.xboxlive.com/connections/"
"https://userpresence.xboxlive.com/users/xuid("
"https://vortex-win.data.microsoft.com"
"https://vortex-events.xboxlive.com"
...

Different endpoints that may be called by the game. These can be useful as filters in Wireshark at some point, but not relevant to the endpoint that we are interested in.

"HCHttpCallPerformAsync"
"HCHttpCallRequestSetHeader [ID %llu]: %s=%s"
"HCHttpCallRequestSetRequestBodyBytes [ID %llu]: requestBodySize=%lu"
"HCHttpCallRequestSetRetryAllowed [ID %llu]: retryAllowed=%s"
"HCHttpCallRequestSetRetryCacheId [ID %llu]: retryAfterCacheId=%d"
"HCHttpCallRequestSetTimeout [ID %llu]: timeoutInSeconds=%u"
"HCHttpCallRequestTimeoutWindow: %u"
"HCHttpCallRequestSetUrl [ID %llu]: method=%s url=%s"
"HCHttpCallResponseAppendResponseBodyBytes [ID %llu]: bodySize=%llu (total=%llu)"
"HCHttpCallResponseGetResponseString [ID %llu]: responseString=%.2048s"
"HCHttpCallResponseSetResponseHeader [ID %llu]: Duplicated header %s=%s"
"HCHttpCallResponseSetResponseHeader [ID %llu]: %s=%s"
"HCHttpCallResponseSetErrorCode [ID %llu]: errorCode=%08X (%08X)"
"HCHttpCallResponseSetErrorMessage [ID %llu]: errorMessage=%s"
"HCHttpCallResponseSetResponseBodyBytes [ID %llu]: bodySize=%llu"
"HCHttpCallResponseSetStatusCode [ID %llu]: statusCode=%u"

This is a large set of functions related to constructing HTTP requests and retrieving HTTP responses. These come from the Xbox Live API and the functions that reference these strings seem like good candidates for investigation. There are additional references to libHttpClient, which is another library that works in conjunction with Xbox Live API. The API is pretty comprehensive and provides wrappers for WebSockets, REST APIs, and curl-like functionality with Microsoft’s xCurl implementation. As we begin to reverse engineer the executable, these sets of functions will be good to keep in mind.

Going through the string references has revealed a lot of good information about what is going on with respect to the networking functionality. We were lucky to find that the SSLKEYLOGFILE functionality is supported, and also picked up some good leads regarding functions to investigate. The next series of posts will take a look at these functions, and more, with the goal of finding the relevant code for building requests and processing responses.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

 

Powered by WordPress