mirror of
https://github.com/ufrisk/MemProcFS.git
synced 2026-06-20 00:57:45 +08:00
228 lines
9.4 KiB
C
228 lines
9.4 KiB
C
// m_sys_net.c : implementation related to the Sys/Net built-in module.
|
|
//
|
|
// The 'sys/net' module is responsible for displaying networking information
|
|
// in a 'netstat' like way at the path '/sys/net/'
|
|
//
|
|
// The module is a provider of forensic timelining information.
|
|
//
|
|
// (c) Ulf Frisk, 2020-2026
|
|
// Author: Ulf Frisk, pcileech@frizk.net
|
|
//
|
|
|
|
#include "modules.h"
|
|
|
|
LPCSTR szMSYSNET_README =
|
|
"Information about the sys net module \n" \
|
|
"==================================== \n" \
|
|
"The sys/net module tries to enumerate and list network connections in \n" \
|
|
"Windows 7 and later (x64 only). \n" \
|
|
"--- \n" \
|
|
"Documentation: https://github.com/ufrisk/MemProcFS/wiki/FS_SysInfo_Network \n";
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Net functionality below:
|
|
// Show information related to TCP/IP connectivity in the analyzed system.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#define MSYSNET_LINELENGTH 128ULL
|
|
#define MSYSNET_LINELENGTH_VERBOSE 278ULL
|
|
#define MSYSNET_LINEHEADER " # PID Proto State Src Dst Process"
|
|
#define MSYSNET_LINEHEADER_VERBOSE MSYSNET_LINEHEADER " Time Object Address Process Path"
|
|
|
|
|
|
|
|
VOID MSysNet_ReadLineCB(_In_ VMM_HANDLE H, _Inout_opt_ PVOID ctx, _In_ DWORD cbLineLength, _In_ DWORD ie, _In_ PVMM_MAP_NETENTRY pe, _Out_writes_(cbLineLength + 1) LPSTR szu8)
|
|
{
|
|
PVMM_PROCESS pObProcess = VmmProcessGet(H, pe->dwPID);
|
|
Util_usnprintf_ln(szu8, cbLineLength,
|
|
"%04x%7i %s %s",
|
|
ie,
|
|
pe->dwPID,
|
|
pe->uszText,
|
|
pObProcess ? pObProcess->pObPersistent->uszNameLong : ""
|
|
);
|
|
Ob_DECREF(pObProcess);
|
|
}
|
|
|
|
VOID MSysNet_ReadLineVerboseCB(_In_ VMM_HANDLE H, _Inout_opt_ PVOID ctx, _In_ DWORD cbLineLength, _In_ DWORD ie, _In_ PVMM_MAP_NETENTRY pe, _Out_writes_(cbLineLength + 1) LPSTR szu8)
|
|
{
|
|
CHAR szTime[24];
|
|
PVMM_PROCESS pObProcess = VmmProcessGet(H, pe->dwPID);
|
|
Util_FileTime2String(pe->ftTime, szTime);
|
|
Util_usnprintf_ln(szu8, cbLineLength,
|
|
"%04x%7i %s %-20s %s %016llx %s",
|
|
ie,
|
|
pe->dwPID,
|
|
pe->uszText,
|
|
pObProcess ? pObProcess->pObPersistent->uszNameLong : "",
|
|
szTime,
|
|
pe->vaObj,
|
|
pObProcess ? pObProcess->pObPersistent->uszPathKernel : ""
|
|
);
|
|
Ob_DECREF(pObProcess);
|
|
}
|
|
|
|
NTSTATUS MSysNet_Read(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _Out_writes_to_(cb, *pcbRead) PBYTE pb, _In_ DWORD cb, _Out_ PDWORD pcbRead, _In_ QWORD cbOffset)
|
|
{
|
|
NTSTATUS nt = VMMDLL_STATUS_FILE_INVALID;
|
|
PVMMOB_MAP_NET pObNetMap;
|
|
if(!_stricmp(ctxP->uszPath, "readme.txt")) {
|
|
return Util_VfsReadFile_FromStrA(szMSYSNET_README, pb, cb, pcbRead, cbOffset);
|
|
}
|
|
if(VmmMap_GetNet(H, &pObNetMap)) {
|
|
if(!_stricmp(ctxP->uszPath, "netstat.txt")) {
|
|
nt = Util_VfsLineFixed_Read(
|
|
H, (UTIL_VFSLINEFIXED_PFN_CB)MSysNet_ReadLineCB, NULL, MSYSNET_LINELENGTH, MSYSNET_LINEHEADER,
|
|
pObNetMap->pMap, pObNetMap->cMap, sizeof(VMM_MAP_NETENTRY),
|
|
pb, cb, pcbRead, cbOffset
|
|
);
|
|
}
|
|
if(!_stricmp(ctxP->uszPath, "netstat-v.txt")) {
|
|
nt = Util_VfsLineFixed_Read(
|
|
H, (UTIL_VFSLINEFIXED_PFN_CB)MSysNet_ReadLineVerboseCB, NULL, MSYSNET_LINELENGTH_VERBOSE, MSYSNET_LINEHEADER_VERBOSE,
|
|
pObNetMap->pMap, pObNetMap->cMap, sizeof(VMM_MAP_NETENTRY),
|
|
pb, cb, pcbRead, cbOffset
|
|
);
|
|
}
|
|
Ob_DECREF(pObNetMap);
|
|
}
|
|
return nt;
|
|
}
|
|
|
|
BOOL MSysNet_List(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _Inout_ PHANDLE pFileList)
|
|
{
|
|
PVMMOB_MAP_NET pObNetMap;
|
|
if(ctxP->uszPath[0]) { return FALSE; }
|
|
VMMDLL_VfsList_AddFile(pFileList, "readme.txt", strlen(szMSYSNET_README), NULL);
|
|
if(VmmMap_GetNet(H, &pObNetMap)) {
|
|
VMMDLL_VfsList_AddFile(pFileList, "netstat.txt", UTIL_VFSLINEFIXED_LINECOUNT(H, pObNetMap->cMap) * MSYSNET_LINELENGTH, NULL);
|
|
VMMDLL_VfsList_AddFile(pFileList, "netstat-v.txt", UTIL_VFSLINEFIXED_LINECOUNT(H, pObNetMap->cMap) * MSYSNET_LINELENGTH_VERBOSE, NULL);
|
|
Ob_DECREF(pObNetMap);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID MSysNet_Timeline(
|
|
_In_ VMM_HANDLE H,
|
|
_In_opt_ PVOID ctxfc,
|
|
_In_ HANDLE hTimeline,
|
|
_In_ VOID(*pfnAddEntry)(_In_ VMM_HANDLE H, _In_ HANDLE hTimeline, _In_ QWORD ft, _In_ DWORD dwAction, _In_ DWORD dwPID, _In_ DWORD dwData32, _In_ QWORD qwData64, _In_ LPCSTR uszText),
|
|
_In_ VOID(*pfnEntryAddBySql)(_In_ VMM_HANDLE H, _In_ HANDLE hTimeline, _In_ DWORD cEntrySql, _In_ LPCSTR *pszEntrySql)
|
|
) {
|
|
DWORD i;
|
|
PVMM_MAP_NETENTRY pe;
|
|
PVMMOB_MAP_NET pObNetMap;
|
|
if(VmmMap_GetNet(H, &pObNetMap)) {
|
|
for(i = 0; i < pObNetMap->cMap; i++) {
|
|
pe = pObNetMap->pMap + i;
|
|
if(pe->ftTime && pe->uszText[0]) {
|
|
pfnAddEntry(H, hTimeline, pe->ftTime, FC_TIMELINE_ACTION_CREATE, pe->dwPID, 0, pe->vaObj, pe->uszText);
|
|
}
|
|
}
|
|
Ob_DECREF(pObNetMap);
|
|
}
|
|
}
|
|
|
|
VOID MSysNet_FcLogCSV(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ VMMDLL_CSV_HANDLE hCSV)
|
|
{
|
|
static LPCSTR szSTATES[] = {
|
|
"CLOSED",
|
|
"LISTENING",
|
|
"SYN_SENT",
|
|
"SYN_RCVD",
|
|
"ESTABLISHED",
|
|
"FIN_WAIT_1",
|
|
"FIN_WAIT_2",
|
|
"CLOSE_WAIT",
|
|
"CLOSING",
|
|
"LAST_ACK",
|
|
"",
|
|
"",
|
|
"TIME_WAIT",
|
|
""
|
|
};
|
|
CHAR szTime[24];
|
|
DWORD iNetMap, dwIpVersion;
|
|
PVMM_MAP_NETENTRY pe;
|
|
PVMMOB_MAP_NET pObNetMap = NULL;
|
|
PVMM_PROCESS pObProcess = NULL;
|
|
if(ctxP->pProcess) { return; }
|
|
if(!VmmMap_GetNet(H, &pObNetMap)) { goto fail; }
|
|
FcFileAppend(H, "net.csv", "Proto,State,SrcAddr,SrcPort,DstAddr,DstPort,Time,Object,PID,Process,ProcessPath\n");
|
|
for(iNetMap = 0; iNetMap < pObNetMap->cMap; iNetMap++) {
|
|
Ob_DECREF_NULL(&pObProcess);
|
|
pe = pObNetMap->pMap + iNetMap;
|
|
pObProcess = VmmProcessGet(H, pe->dwPID);
|
|
Util_FileTime2String(pe->ftTime, szTime);
|
|
dwIpVersion = (pe->AF == AF_INET) ? 4 : (((pe->AF == 23 /* AF_INET6 */)) ? 6 : 0);
|
|
FcCsv_Reset(hCSV);
|
|
FcFileAppend(H, "net.csv", "%s%i,%s,%s,%i,%s,%i,%s,0x%llx,%i,%s,%s\n",
|
|
((pe->dwPoolTag == 'UdpA') ? "UDP" : "TCP"), dwIpVersion,
|
|
FcCsv_String(hCSV, (LPSTR)szSTATES[pe->dwState]),
|
|
pe->Src.uszText,
|
|
pe->Src.port,
|
|
pe->Dst.uszText,
|
|
pe->Dst.port,
|
|
FcCsv_String(hCSV, szTime),
|
|
pe->vaObj,
|
|
pe->dwPID,
|
|
FcCsv_String(hCSV, pObProcess ? pObProcess->pObPersistent->uszNameLong : ""),
|
|
FcCsv_String(hCSV, pObProcess ? pObProcess->pObPersistent->uszPathKernel : "")
|
|
);
|
|
}
|
|
fail:
|
|
Ob_DECREF(pObNetMap);
|
|
Ob_DECREF(pObProcess);
|
|
}
|
|
|
|
VOID MSysNet_FcLogJSON(_In_ VMM_HANDLE H, _In_ PVMMDLL_PLUGIN_CONTEXT ctxP, _In_ VOID(*pfnLogJSON)(_In_ VMM_HANDLE H, _In_ PVMMDLL_FORENSIC_JSONDATA pData))
|
|
{
|
|
PVMMDLL_FORENSIC_JSONDATA pd;
|
|
PVMMOB_MAP_NET pObNetMap = NULL;
|
|
PVMM_MAP_NETENTRY pe;
|
|
DWORD i;
|
|
PVMM_PROCESS pObProcess = NULL;
|
|
CHAR szTime[24], szu[MAX_PATH];
|
|
if(ctxP->pProcess || !(pd = LocalAlloc(LMEM_ZEROINIT, sizeof(VMMDLL_FORENSIC_JSONDATA)))) { return; }
|
|
pd->dwVersion = VMMDLL_FORENSIC_JSONDATA_VERSION;
|
|
pd->szjType = "net";
|
|
if(VmmMap_GetNet(H, &pObNetMap)) {
|
|
for(i = 0; i < pObNetMap->cMap; i++) {
|
|
pe = pObNetMap->pMap + i;
|
|
szu[0] = 0;
|
|
if((pObProcess = VmmProcessGet(H, pe->dwPID))) {
|
|
Util_FileTime2String(pe->ftTime, szTime);
|
|
snprintf(szu, _countof(szu), "proc:[%s] time:[%s] path:[%s]",
|
|
pObProcess ? pObProcess->pObPersistent->uszNameLong : "",
|
|
szTime,
|
|
pObProcess ? pObProcess->pObPersistent->uszPathKernel : "");
|
|
Ob_DECREF_NULL(&pObProcess);
|
|
}
|
|
pd->i = i;
|
|
pd->dwPID = pe->dwPID;
|
|
pd->vaObj = pe->vaObj;
|
|
pd->usz[0] = pe->uszText;
|
|
pd->usz[1] = szu;
|
|
pfnLogJSON(H, pd);
|
|
}
|
|
}
|
|
Ob_DECREF(pObNetMap);
|
|
LocalFree(pd);
|
|
}
|
|
|
|
VOID M_SysNet_Initialize(_In_ VMM_HANDLE H, _Inout_ PVMMDLL_PLUGIN_REGINFO pRI)
|
|
{
|
|
if((pRI->magic != VMMDLL_PLUGIN_REGINFO_MAGIC) || (pRI->wVersion != VMMDLL_PLUGIN_REGINFO_VERSION)) { return; }
|
|
if((pRI->tpSystem != VMMDLL_SYSTEM_WINDOWS_64) && (pRI->tpSystem != VMMDLL_SYSTEM_WINDOWS_32)) { return; }
|
|
strcpy_s(pRI->reg_info.uszPathName, 128, "\\sys\\net"); // module name
|
|
pRI->reg_info.fRootModule = TRUE; // module shows in root directory
|
|
pRI->reg_fn.pfnList = MSysNet_List; // List function supported
|
|
pRI->reg_fn.pfnRead = MSysNet_Read; // Read function supported
|
|
pRI->reg_fnfc.pfnTimeline = MSysNet_Timeline; // Timeline supported
|
|
pRI->reg_fnfc.pfnLogCSV = MSysNet_FcLogCSV; // CSV log function supported
|
|
pRI->reg_fnfc.pfnLogJSON = MSysNet_FcLogJSON; // JSON log function supported
|
|
memcpy(pRI->reg_info.sTimelineNameShort, "Net", 4);
|
|
strncpy_s(pRI->reg_info.uszTimelineFile, 32, "timeline_net", _TRUNCATE);
|
|
pRI->pfnPluginManager_Register(H, pRI);
|
|
}
|