top of page
  • Writer's pictureISSP

Decrypting the code: a deep dive into Frida's traffic interception capabilities

We continue to introduce you to the practical applications of the Frida tool. Today, we will delve into how it can be utilized to intercept traffic, including encrypted traffic. Examining traffic can be quite challenging, particularly in situations where installing a certificate is impossible due to SSL pinning. However, through dynamic analysis methods, this can be done directly in memory without significant issues.


We will explain Frida's practical application using the following example:

Frida's traffic interception capabilities

It's worth mentioning that the easiest way to use cURL library with Visual Studio is by using Vcpkg.


One primary challenge is determining the address of the "writeFunction." How can this be accomplished? Start by intercepting curl_easy_setopt and filtering it by the second parameter to eliminate unnecessary data at this stage. To do this, try locating curl_easy_setopt using the following code:

Module.findExportByName("libcurl.dll", "curl_easy_setopt").

However, libcurl may not always be an independent library. It is often linked within the executable file. To address this issue, try finding the function in a decompiler or compile the library yourself using the same compiler parameters as the executable file. The main parameter we are interested in here is the optimization level. Additionally, you'll need to identify the appropriate compiler version. As an alternative, you can use Detect Is Easy (with Nauz file detector).

Frida's traffic interception capabilities

To achieve this goal in certain situations, it can be helpful to use a tool like Godbolt. Afterward, open any disassembler and review the exports, searching for the required function.

Frida's traffic interception capabilities

Next, using the disassembler, examine the exports for the desired function. Initially, attempt to match the byte pattern to the distinctive elements of the function (typically, the function's beginning works well for this).


If this approach doesn't yield results, verify if the function utilizes any distinctive constants, such as debug strings at the function's beginning. Locate these constants by switching to the decompiler and examining the source file under investigation. Search for all constants and similar code within this file.

Frida's traffic interception capabilities

If this approach also proves unsuccessful, inspect nested functions and attempt to trace the chain of calls upward, where the subsequent function might be more explicitly expressed in the code. This method is also effective (and sometimes even simpler) with library calls, allowing you to easily find the necessary function. Typically, we discover the required function during one of these stages.


In rare cases where none of these methods help, try to find the functions visually, which requires some skill in quickly analyzing the decompiler's output and comparing it to the original code. These skills can be acquired without much difficulty by investing a little time in learning them.


Moving forward, we will continue using the set of scripts from the previous article, only changing script.js. Exploring the Benefits and Use of the Frida Toolkit.

We have two options: either set an offset from the start of the module and recalculate the address each time, or use Memory.scan:

Frida's traffic interception capabilities

Personally, I prefer the second method, as it typically works even with minor version changes to the file during the investigation. It's worth noting that well-chosen patterns can withstand significant changes, but that's a topic for separate articles. So, let's proceed with the option where the function is simply exported from the library under a specific name and try to obtain the address of the writeFunction function:

Frida's traffic interception capabilities

where CURLOPT_WRITEFUNCTION is used (it's amazing how powerful these modern IDEs are; Notepad++ just can't compete):

Frida's traffic interception capabilities

We've found the function we need to intercept. Now, I suggest defining this function in a new way using NativeCallback (this is convenient in this case, but using NativeFunction in the future will allow calling these functions as needed):

Frida's traffic interception capabilities

As a result, we get:

Frida's traffic interception capabilities

As you can see, everything appears somewhat convoluted, but it can all be easily sorted out if necessary. You can also obtain not only the response but also the request, URL, and POST data. I'll leave this for you to experiment with.


In conclusion, using the Frida tool for intercepting traffic can be an effective method for analyzing network interactions, especially when traditional methods, such as installing certificates, are not available. Although searching for and identifying the necessary functions may require significant effort and skill, following the methods described here can significantly simplify the process.


Using Frida for dynamic analysis in memory allows technical specialists to access vital information about the operation of applications and their network interactions. This, in turn, can help detect and address potential security issues.


Working materials are available at the following link: https://github.com/bilka00/frida_series_of_notes


Want to know more about Reverse Engineering? Check out our Reverse Engineering with Ghidra article.


To learn more about ISSP Professional Services please visit ISSP Labs and resource center.

Comments


bottom of page