FriendlyFire BOF: Selective Process Freezing

Introduction

The objective of this research was to find a way to suppress Microsoft Teams’ ability to display new messages without forcefully terminating the application or making it visibly unresponsive. The approach taken involved analyzing the process tree, identifying dependencies, and selectively suspending non-essential threads.

This document outlines the methodology used, the technical findings, and the final implementation of a proof-of-concept tool that achieves this functionality.

Identifying the Relevant Processes

The first step was to analyze how Microsoft Teams operates at the process level. Using Process Monitor and Process Hacker, I examined the child processes spawned by ms-teams.exe.

One process stood out: msedgewebview2.exe.

Process Monitor

This process is responsible for rendering Teams' WebView-based UI components, similar to how embedded WebViews work in mobile applications. This meant that rather than modifying ms-teams.exe directly, it was likely more effective to target msedgewebview2.exe, as it handled the actual rendering of messages.

By monitoring msedgewebview2.exe, I confirmed that it was responsible for updating chat messages and other UI elements. The next step was to determine how to selectively halt message rendering without freezing the entire UI.

Network Analysis: Examining Message Fetching

To validate whether messages were being fetched dynamically via network calls, Wireshark was used to inspect Teams' encrypted traffic.

Wireshark monitoring

Key observations:

  • The relevant traffic was directed to subdomains such as teams.live.com and s-0005.s-msedge.net
  • The messages were transmitted via TLS-encrypted WebSocket communication.
  • Attempting to decrypt TLS using exported session keys did not immediately yield readable message content.

At this stage, an alternative approach was necessary. Rather than interfering with network traffic, it was more practical to manipulate process execution.

Process Manipulation: Suspending Non-UI Threads

The key challenge was to prevent message updates without fully freezing the Teams UI. The hypothesis was that suspending specific threads within msedgewebview2.exe would stop message updates while keeping the interface functional.

A proof-of-concept was developed to:

  1. Enumerate all threads within the target process.
  2. Identify which threads were responsible for UI elements.
  3. Suspend all non-UI threads to block background updates.

To determine whether a thread was UI-related, the EnumThreadWindows function was used:

BOOL CALLBACK EnumThreadWndProc(HWND hwnd, LPARAM lParam) {  
    EnumData* pData = (EnumData*)lParam;  
    pData->found = TRUE;  
    return FALSE; // Stop enumeration once a window is found  
}  

BOOL IsGuiThread(DWORD dwThreadId) {  
    EnumData data = { FALSE };  
    EnumThreadWindows(dwThreadId, EnumThreadWndProc, (LPARAM)&data);  
    return data.found;  
}

Threads that did not own any UI windows were considered background processing threads and were candidates for suspension.

Using Thread32First and Thread32Next, the PoC iterated over all threads, checking if they were UI-related. If not, they were suspended using SuspendThread:

if (!IsGuiThread(te.th32ThreadID)) {  
    HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);  
    if (hThread) {  
        if (SuspendThread(hThread) == (DWORD)-1) {  
            printf("[-] Failed to suspend thread %d\n", te.th32ThreadID);  
        } else {  
            printf("[+] Suspended thread %d\n", te.th32ThreadID);  
        }  
        CloseHandle(hThread);  
    } else {  
        printf("[-] Unable to open thread %d\n", te.th32ThreadID);  
    }  
}

This implementation was semi functional. At this point, the UI looks functional, but clicking buttons does nothing, network connection is still active in the process though so we didn't hit the networking threads.

Testing and Refinement

Initial testing targeted ms-teams.exe directly, but this produced inconsistent results. While some background processes stopped, certain UI elements remained functional or network connection was still active in the process.

Upon targeting msedgewebview2.exe instead, it became clear that:

  • Suspending all non-UI threads within this process completely halted message updates.
  • The Teams interface remained responsive, but no new messages were displayed.
  • Once the threads were resumed, messages appeared again without any visible issues.
Suspended all threads in msedgewebview2.exe

It should be noted that ms-teams.exe had multiple child processes named msedgewebview2.exe. Suspending all non-UI threads on each one returned different results in terms of how the UI behaved while suspended. There is one specific instance of the child process that is better than the others to suspend, I decided not to add logic to identify this in order to maintain the versatility of the tool to be able to target all processes. If you were going for extreme stealth or targeting a very specific component of a process, you could implement this into the BOF.

ms-teams.exe process tree

To make the tool more robust and make sure that we are not just causing uncontrolled disruption to users, logic was added to allow thread resumption on demand, ensuring that normal operation could be restored once the operator issued the resume command on the target PID:

if (!IsGuiThread(te.th32ThreadID)) {  
    HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);  
    if (hThread) {  
        if (resumeMode) {  
            if (ResumeThread(hThread) == (DWORD)-1) {  
                printf("[-] Failed to resume thread %d\n", te.th32ThreadID);  
            } else {  
                printf("[+] Resumed thread %d\n", te.th32ThreadID);  
            }  
        }  
        CloseHandle(hThread);  
    }
}

Final Implementation and Broader Applications

Once testing confirmed the effectiveness of this approach, the PoC was refined into a Beacon Object File implementation for Cobalt Strike. This allowed integration into red team toolkits for stealthy process manipulation.

Although this research initially focused on Microsoft Teams, the same approach applies to other scenarios, such as:

  • Pausing specific browser tabs running WebView-based content.
  • Temporarily disabling background processing in other applications, including chat clients and VPNs.
  • Suspending security tools without terminating them outright.

By suspending non-UI threads, the target application remains visually operational while its background functionality is disabled.

Conclusion

This technique demonstrates that full process termination is not always necessary to achieve operational goals. By selectively suspending specific threads, it is possible to manipulate application behavior without triggering immediate suspicion.

While this method does not represent a novel exploitation technique, it highlights how low-level process manipulation can be leveraged effectively in offensive security scenarios.

For those interested in experimenting with this approach, the final BOF implementation is available here:
🔗 FriendlyFire

The other main objective of this post was to unveil the analysis and thought process behind building adversary tooling. Demonstrating this process through simpler tooling like this one, can be a great way to learn.

Happy hacking!