Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit 70f2f04b794cc8039186f490564bfefda587d549
Author: H4NM <[email protected]>
Date:   Mon Jan 6 20:41:43 2025 +0100

    - Added a summary text file
    - Changed file names to be shorter and more concise
    - Change default process name when unable to sucesfully map it
    - Change compiled executable name from WhoYouCalling.exe to wyc.exe - its a cli tool after all :-).
    - Fix so that the DNS wireshark filter folder is not created if there are no wireshark filters to be created
    - Fix issue where entire BPF filter was not written to file
    - Solve issue with short lived processes that perform DNS queries that do not have process names included.
    - Solve issue where the DNS ETW event registers the process PID before the process start ETW does, causes for adding a process twice.
    - Implement fix against race condition issue with short lived processes that perform DNS queries as they're labeled as unmapped processes.
      * This is done by checking if the unmapped process has the same PID as the correctly mapped process and if it was added to monitoring close to the same time
    - Solve issue for possible duplicate processname, indicating they're the same process, although launched separately and happend to get the same PID. Likely hood is very small but it could happen that would make results add to the same process even though they're separate.
    - Remove JSON flag and create the JSON file regardless to avoid scenarios of missing crucial data.
    - Added a spinner wheel to filtering processes
    - Updated and cleaned up README
    - Refactoring and cleaning code
    - Changed default values for process start and stop time, and executable name to null for cleaner and consistent data output
    - Added github actions to ensure that wyc can be compiled
  • Loading branch information
H4NM committed Jan 6, 2025
1 parent 2ce0a87 commit d5ea74b
Show file tree
Hide file tree
Showing 22 changed files with 1,039 additions and 343 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Compile WhoYouCalling

on:
push:
branches:
- main

jobs:
build:
runs-on: windows-latest

steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0'

- name: Restore dependencies
run: dotnet restore

- name: Compile solution
run: dotnet build --configuration Release

41 changes: 24 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ However, there are some downsides:
- Monitor every running process simultaneously.
- Create a full packet capture (.pcap) file per process.
- Monitor processes based on process name.
- Run executables as other users and in elevated and unelevated state.
- Run executables as other users and in elevated or unelevated state.
- Record TCPIP activities, IPv4 and IPv6.
- Record DNS requests and responses.
- Create Wireshark filter based on DNS responses for domains.
Expand Down Expand Up @@ -58,7 +58,7 @@ wyc.exe --illuminate --interface 8

**Execute a binary with arguments. Output the results to a folder on the user desktop**:
```
wyc.exe --execute C:\Users\H4NM\Desktop\TestApplication.exe --arguments "--pass=ETph0n3H0m3" --interface 4 --output C:\Users\H4NM\Desktop
wyc.exe --executable C:\Users\H4NM\Desktop\TestApplication.exe --arguments "--pass=ETph0n3H0m3" --interface 4 --output C:\Users\H4NM\Desktop
```

**Listen to process with PID 24037 and skip packet capture**:
Expand All @@ -84,7 +84,7 @@ There are other tools that can compliment your quest of application network anal
- [Windows Sandbox](https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-overview): A simple and native sandbox in Windows. I strongly recommend using a sandbox or VM when when executing unknown applications. There's also the possibility of adding your own configuration for the Windows Sandbox to harden it a bit further or include WhoYouCalling with the sandbox on start. See more [here](https://learn.microsoft.com/en-us/windows/security/application-security/application-isolation/windows-sandbox/windows-sandbox-configure-using-wsb-file)

### Limitations
- **DNS**: In ETW, `Microsoft-Windows-DNS-Client` only logs A and AAAA queries, neglecting other DNS query types such as PTR, TXT, MX, SOA etc. It does capture CNAME and it's respective adresses, which are part of the DNS response. However, with the FPC the requests are captured either way, just not portrayed as in registered DNS traffic by the application.
- **DNS**: In ETW, `Microsoft-Windows-DNS-Client` only logs A and AAAA queries, neglecting other DNS query types such as PTR, TXT, MX, SOA etc. It does capture CNAME and it's respective adresses, which are part of the DNS response. However, with the FPC the requests are captured either way, just not portrayed as in registered DNS traffic by the application. The FPC and registered TCPIP activity helps identify processes that do not utilize **Windows DNS Client Service** (e.g. `nslookup`) since they're not logged in the DNS ETW.
- **Execution integrity**: It's currently not possible to delegate the privilege of executing applications in an elevated state to other users, meaning that if you want to run the application elevated you need to be signed in as the user with administrator rights.
Since WhoYouCalling requires elevated privileges to run (*ETW + FPC*), spawned processes naturally inherits the security token making them also posess the same integrity level - and .NET api does not work too well with creating less privileged processes from an already elevated state.
The best and most reliable approach was to duplicate the low privileged token of the desktop shell in an interactive logon (explorer.exe).
Expand All @@ -98,33 +98,41 @@ This project has been tested and works with .NET 8 with two nuget packages, and
- ETW: [Microsoft.Diagnostics.Tracing.TraceEvent](https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent/)


- ### Installing/Compiling Instructions

Follow these steps to compile and run the project from source:

### Installing/Compiling instructions
Follow these steps for compiling from source:
1. Make sure [.NET 8](https://learn.microsoft.com/en-us/dotnet/core/install/windows) is installed
1. **Install .NET 8**
Ensure [.NET 8](https://learn.microsoft.com/en-us/dotnet/core/install/windows) is installed on your system.

2. (**Optional**) - Download and install [npcap](https://npcap.com/#download). It enables packet capture in Windows. It's not needed if the flag for not capturing packets is provided.
2. **(Optional) Install Npcap**
Download and install [Npcap](https://npcap.com/#download) to enable packet capture in Windows.
> **Note:** Npcap is not required and you may provide the flag to disable packet capture when running the program.
3. Download this repo
```
3. **Clone the Repository**
Download the source code by cloning this repository:
```sh
git clone https://github.com/H4NM/WhoYouCalling.git
```

4. Enter project
```
4. **Enter project**
```sh
cd WhoYouCalling
```

5. Install the related packages (SharpCap and TraceEvent).
5. **Install the related packages (SharpCap and TraceEvent).**
```
dotnet restore
```

6. Build
6. **Build the project**
```
dotnet publish -c Release -r win-(x64 or x86) --self-contained true
dotnet publish -c Release -r win-x64 --self-contained true
```

7. Run
7. **Run it**
```
bin\Release\net8.0\win-x64\wyc.exe [arguments]...
```
Expand All @@ -133,10 +141,9 @@ bin\Release\net8.0\win-x64\wyc.exe [arguments]...
# 🐛 Bugs or Requests? ✨ Create an issue! 🚀

### To Do:
- Refactor. Lots and lots to refactor and make more tidy :)
- Add a summary text report

### Nice to have
- Refactor. Lots and lots to refactor and make more tidy :)
- Network graph visualizing the process tree and summarized network traffic by each process
- IP and domain name lookup option to get reputation

### Nice to have
- Process network redirect to proxy for TLS inspection
2 changes: 1 addition & 1 deletion WhoYouCalling.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x64;x86</Platforms>
<FileVersion>1.3.3</FileVersion>
<FileVersion>1.4</FileVersion>
<ApplicationManifest>WhoYouCalling\app.manifest</ApplicationManifest>
<AssemblyName>wyc</AssemblyName>
</PropertyGroup>
Expand Down
2 changes: 2 additions & 0 deletions WhoYouCalling/Constants/FileNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ static class FileNames
public const string RootFolderBPFFilterFileName = "Combined BPF-filter.txt";
public const string RootFolderETWHistoryFileName = "Events.txt";
public const string RootFolderJSONProcessDetailsFileName = "Result.json";
public const string RootFolderSummaryProcessDetailsFileName = "Summary.txt";


//// Per Process
public const string ProcessFolderPcapFileName = "Packet capture.pcap";
Expand Down
4 changes: 3 additions & 1 deletion WhoYouCalling/Constants/Miscellaneous.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace WhoYouCalling.Constants
static class Miscellaneous
{
public const Int32 NotApplicableStatusNumber = 999999;
public const string ProcessDefaultNameAtError = "NA";
public const Int32 CustomWindowsDNSStatusCode = 87;
public const Int32 MaxSecondsUnmappedProcessRange = 3;
public const string UnmappedProcessDefaultName = "UnmappedProcess";
public static readonly List<string> SpinnerChars = new List<string>
{
"-", "/", "|", "\\"
Expand Down
17 changes: 6 additions & 11 deletions WhoYouCalling/ETW/DNSClientListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,13 @@ private void DnsClientEvent(TraceEvent data)
string processName = Program.GetMonitoredProcessName(pid: data.ProcessID, processName: data.ProcessName);
ProcessDnsQuery(data, processName);
}
else if ((Program.TrackProcessesByName() && Program.IsTrackedProcessByName(pid: data.ProcessID, processName: data.ProcessName)) || Program.MonitorEverything())
else if (Program.MonitorEverything() || (Program.TrackProcessesByName() && Program.IsTrackedProcessByName(pid: data.ProcessID, processName: data.ProcessName)))
{
string processName = Program.GetNewProcessName(pid: data.ProcessID, processName: data.ProcessName);

Program.AddProcessToMonitor(pid: data.ProcessID, processName: processName);

if (string.IsNullOrEmpty(processName) || processName == Constants.Miscellaneous.ProcessDefaultNameAtError)
if (!Program.IsMonitoredProcess(pid: data.ProcessID, processName: processName)) // This is to deal with race conditions as the DNS ETW registers before process starts sometimes, where it is added before the actua
{
processName = Program.GetBackupProcessName(data.ProcessID);
Program.AddProcessToMonitor(pid: data.ProcessID, processName: processName);
}

ProcessDnsQuery(data, processName);
Expand All @@ -125,16 +123,13 @@ private void DnsClientEvent(TraceEvent data)
string processName = Program.GetMonitoredProcessName(pid: data.ProcessID, processName: data.ProcessName);
ProcessDnsResponse(data, processName);
}
else if ((Program.TrackProcessesByName() && Program.IsTrackedProcessByName(pid: data.ProcessID, processName: data.ProcessName)) || Program.MonitorEverything())
else if (Program.MonitorEverything() || (Program.TrackProcessesByName() && Program.IsTrackedProcessByName(pid: data.ProcessID, processName: data.ProcessName)))
{

string processName = Program.GetNewProcessName(pid: data.ProcessID, processName: data.ProcessName);

Program.AddProcessToMonitor(pid: data.ProcessID, processName: processName);

if (string.IsNullOrEmpty(processName) || processName == Constants.Miscellaneous.ProcessDefaultNameAtError)
if (!Program.IsMonitoredProcess(pid: data.ProcessID, processName: processName)) // This is to deal with race conditions as the DNS ETW registers before process starts sometimes, where it is added before the actua
{
processName = Program.GetBackupProcessName(data.ProcessID);
Program.AddProcessToMonitor(pid: data.ProcessID, processName: processName);
}

ProcessDnsResponse(data, processName);
Expand Down
Loading

0 comments on commit d5ea74b

Please sign in to comment.