Dns被莫名篡改的问题定位(笔记)

引言:最近发现用户的多台机器上出现了Dns被莫名修改的问题,从系统事件上看并未能正常确定到是那个具体软件所为,现在的需求就是确定和定位哪个软件具体所为。

解决思路:
  1. 首先到IPv4设置页面对Dns进行设置:
  2. 通过ProcExp确定了该窗口的宿主进程是Explorer.exe,通过ProcMon对Explorer进行监控,并未发现Explorer将静态Dns的地址写入注册表(后来发现其实Explorer是通过DllHost.exe来实现对注册表修改的,所以没监控到)。
  3. 通过对Explorer进行逆向分析发现Explorer实现比较复杂,后来通过网络发现修改Dns可以通过Netsh.exe这个程序来实现:
  4. 于是转到对Netsh.exe的逆向分析上来,经过仔细分析,发现Netsh.exe对dns的修改是通过netiohlp.dll的NhIpHandleSetDnsServer来实现的:

     
  5. 通过进一步定位发现是NhIpAddDeleteSetServer:
  6. 并发现会通过写入注册表来保存相关信息:

    并通过定位发现注册表地址是:
  7. 并且有重启Dnscahe服务等相关操作:
  8. 1)通过设置系统全局钩子来挂钩系统下所有进程然后挂钩SetRegvalue等api监控,该进程通过SetWindowHookEx来设置全局钩子(其实该挂钩方式不能挂钩没有消息循环的经常),通过inject-helper.exe进程来挂钩发现不能挂钩系统下的所有进程,而且新创建的进程也无法挂钩。
    2)通过设置KnowDlls注册表发现也无法正常挂钩所有进程。
    3)通过底层驱动挂钩,这个方法能监控到应用层的所有进程对注册表的操作,但为了回溯到目标进程,可能也需要加入对父子进程的回溯,这个相对麻烦一些。
  9. 笔者采用相对比较简单容易操作的方法。采用ProcMon来对注册表的监控:

    1)设置第一项筛选:operation is RegSetValue 操作

    2)设置第二项筛选:path is HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{33701f65-c437-47a4-9162-071bd72b3425}\NameServer (复制这个字符串修改UUID即可)

    最后的效果如下图:

    设置好后可以看到监控效果:

  10. 但是我们需要追踪最初始的设置Dns的进程,比如进程A调用了Netsh或DllHost等其他的三方进程来设置Dns,这个时候仅仅监控到Netsh或者DllHost等进程是没用的,需要对进程进行父进程的回溯,才知道源操作进程。
  11. 这个时候需要写一个ProcMon的插件,然后在ProcMon在监控到操作进程后能第一时间对父进程进行回溯。

    编写一个Dll插件,并通过窗口子类化方式来对ProcMon的ListView控件进行消息监控:
     
    static DWORD WINAPI DoWork(LPVOID param)
     {
         swprintf_s(g_szProfilePath, L"%s\\record_%d.log", GetCurrentExePath().c_str(), GetCurrentProcessId());
        
         do {
             HWND hwndTaskManager = FindWindowW(L"PROCMON_WINDOW_CLASS", L"Process Monitor - Sysinternals: www.sysinternals.com");
             if (!hwndTaskManager)
             {
                 MessageBox(NULL, L"查找进程窗口失败", L"错误", NULL);
                 break;
             }
             DWORD TaskManagerPID = 0;
             GetWindowThreadProcessId(hwndTaskManager, &TaskManagerPID);
             if (TaskManagerPID != GetCurrentProcessId())
             {
                 MessageBox(NULL, L"TaskManagerPID != GetCurrentProcessId()", L"错误", NULL);
                 break;
             }
             //EnumChildWindows(hwndTaskManager, _EnumChildProc, NULL);
             g_hListView = FindWindowExW(hwndTaskManager, NULL, L"SysListView32", L"");
             if (!g_hListView)
             {
                 MessageBox(NULL, L"获取listview句柄为空", L"错误", NULL);
                 break;
             }
    
             fnOriginNetworkList = (WNDPROC)SetWindowLongPtrW(
                 g_hListView,
                 GWLP_WNDPROC,
                 (LONG_PTR)NetworkListWndProc);
         } while (0);
         return 0;
     }
    // 这里是ListView控件的消息处理函数 
    LRESULT CALLBACK NetworkListWndProc(
         HWND hwnd,      // handle to window
         UINT_PTR uMsg,      // message identifier
         WPARAM wParam,  // first message parameter
         LPARAM lParam   // second message parameter
     )
     {
         if (uMsg == LVM_SETITEMTEXT || uMsg == LVM_SETITEMTEXTA || uMsg == 4211)
         { 
             wchar_t szSection[50] = { 0 };
             wsprintf(szSection, L"%d_%d", g_iPrevItem, pItem->iItem);
             wchar_t szSubItem[50] = { 0 };
             wsprintf(szSubItem, L"%d", pItem->iSubItem);
             WritePrivateProfileStringW(szSection, szSubItem, pItem->pszText, g_szProfilePath);
    
             if (pItem->iSubItem == 3) // process ID
             {
                 time_t tm = time(NULL);
                 struct tm now;
                 localtime_s(&now, &tm);
                 wchar_t str[100] = { 0 };
                 wcsftime(str, sizeof(str) / 2, L"%A %c", &now);
                 WritePrivateProfileStringW(szSection, L"time", str, g_szProfilePath);
    
                 DWORD pid = _wtoi(pItem->pszText);
                 stuProcNode node = { _wtoi(pItem->pszText), szSection };
                 PushProcNodeQueue(node);  // 这里不卡顿消息线程,把父进程回溯抛到另一个独立线程处理
             }
         }
    
         LRESULT rc = CallWindowProc(
             fnOriginNetworkList,
             hwnd,
             uMsg,
             wParam,
             lParam);
    
         return rc;
     }
    // 这里是父进程回溯操作
    static DWORD WINAPI  DoQueryProcess(LPVOID param)
     {
         while (1)
         {
             WaitForSingleObject(g_hQueryProcEvt, INFINITE); // 新的请求进入队列会触发事件
    
             std::vector<stuProcNode> ProcNodeList;
             GetProcNodeQueue(ProcNodeList);
    
             for (int i = 0; i < ProcNodeList.size(); i++)
             {
                 std::wstring strpPidNameList;
                 DWORD pid = ProcNodeList[i].dwPid;
                 while (1)
                 {  
                     // 回溯一下父进程
                     HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
                     if (hProcess == (HANDLE)-1 || hProcess == 0)
                     {
                         break;
                     }
    
                     WCHAR szPath[MAX_PATH] = { 0 };
                     GetProcessImageFileName(hProcess, szPath, MAX_PATH);
    
                     strpPidNameList += L"  [";
                     wchar_t buffer[20] = { 0 };
                     _itow_s(pid, buffer, 20, 10);
                     strpPidNameList += buffer;
                     strpPidNameList += L"  ";
                     strpPidNameList += wcsrchr(szPath, L'\\') ? wcsrchr(szPath, L'\\') + 1 : L"NULL";
                     strpPidNameList += L"]  ";
    
                     PROCESS_BASIC_INFORMATION pbi = { 0 };
                     if (0 == NtQueryInformationProcess(hProcess, 0, &pbi, sizeof(pbi), NULL))
                     {
                         pid = pbi.InheritedFromUniqueProcessId;
                     }
                     else
                     {
                         break;
                     }
                     
                     CloseHandle(hProcess);
                 }
                 WritePrivateProfileStringW(ProcNodeList[i].strSection.c_str(), L"PidNameINFO", strpPidNameList.c_str(), g_szProfilePath);
             }
         }
         return 0;
     }
  12. 代码写好了,这个时候通过CFF软件修改ProcMon的导入表,使其依赖我们的插件,这个时候当ProcMon启动的时候就会自动加载我们的插件了,相当于变相注入到了ProcMon进程。
    看看效果:

  13. 这样的监控程序就算写好了,可以交付运维去部署监控了,一旦监控到就会输出到日志文件,并把父子进程进行了回溯。
  14.  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/762035.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

昇思25天学习打卡营第8天|MindSpore-SSD目标检测

SSD目标检测介绍 SSD,全称Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一种目标检测算法。使用Nvidia Titan X在VOC 2007测试集上,SSD对于输入尺寸300x300的网络,达到74.3%mAP(mean Average Precision)以及59FPS;对于512x512的网络,达到了76.9%mAP ,超…

短视频电商源码怎么选择

随着移动互联网的迅猛发展&#xff0c;短视频电商成为了一种热门的商业模式。很多商家和创业者都希望能够快速搭建一个短视频电商平台来推广和销售自己的产品。然而&#xff0c;选择合适的短视频电商源码并不是一件容易的事情。在选择之前&#xff0c;有一些关键因素需要考虑。…

STC8/32 软硬件I2C通讯方式扫描I2C设备地址

STC8/32 软硬件I2C通讯方式扫描I2C设备地址 📄主要用于检测挂载在I2C总线上的设备。在驱动I2C设备之前,如果能扫描到该设备,说明通讯设备可以连接的上,在提前未知I2C地址的情况下,可以方便后面的驱动代码的完善。 🔬扫描测试效果:(测试mpu6050以及ssd1306 i2c oled )…

本科学历|艺术创业公司经理限定美国西部访问学者申请成功

U经理属于自费访学&#xff0c;本科学历&#xff0c;无文章及课题&#xff0c;但有较丰富的艺术创意及艺术教育实际操作经验&#xff0c;要求申美国西部地区的学校。最终我们为其获得俄勒冈州立大学访问学者邀请函。之前拟定的申请设想全部实现&#xff1a;西部地区、专业契合、…

【Lua小知识】Vscode中Emmylua插件大量报错的解决方法

起因 Vscode写Lua用的好好的&#xff0c;最近突然出现了大量报错。 看报错是有未定义的全局变量&#xff0c;这里查日志才发现是由于0.7.5版本新增诊断启用配置&#xff0c;所以导致了原先好的代码&#xff0c;现在出现了大量的报错。 解决方案一 最直接的方法当然是在配置中直…

【单片机毕业设计选题24040】-基于STM32的蓝牙防丢器设计

系统功能: 系统上电后显示“欢迎使用蓝牙防丢系统请稍后”两秒钟显示正常界面&#xff0c;如果蓝牙正常连接OLED显示Connected, 蓝牙未连接则显示DisConnected同时蜂鸣器报警 蓝牙正常连接后在APP上每隔三秒显示一个Connected 系统功能框图: 主要功能模块原理图: 电源时钟…

CSS|04 复合选择器伪类选择器属性选择器美化超链接

基本选择器&#xff1a;见上篇基本选择器 复合选择器选择器1,选择器2{属性:值;} 多元素选择器&#xff0c;同时匹配选择器1和选择器2&#xff0c;多个选择器之间用逗号分隔举例&#xff1a; p,h1,h2{margin:0px;}E F{属性:值;} 后代元素选择器&#xff0c;匹配所有属于E元素后…

【Python机器学习】模型评估与改进——分组交叉验证

分组交叉验证是非常常见的一种交叉验证策略&#xff0c;它适用于数据中的分组高度相关时。比如我们想构建一个从人脸图片中识别情感的系统&#xff0c;并且收集了100个人的照片的数据集&#xff0c;其中每个人都进行了多次拍摄&#xff0c;分别展示了不同的情感。我们的目标是构…

Python 文件操作

文件编码 将文件的内容翻译为二进制 文件操作 打开文件 open函数 语法&#xff1a; open(name, mode, encoding)name&#xff1a;文件名的字符串&#xff0c;可以包含具体路径。若没有路径&#xff0c;则默认为与py文件位于同一层 mode&#xff1a;打开文件的模式&#xf…

PP-JITTER \RMS-JITTER 及其他Jitter解析

Jitter概念 Jitter(抖动)是从时域评价时钟信号质量的重要参数。 首先要明确的是它是一个统计量,因此有标准差(均方根,rms)和范围(峰峰值,p2p); 然后根据样本的类型可以划分成不同的分类,如Jabs(absolute jitter)、Jp(period jitter)、Jc2c(cycle-to-cycle ji…

Forecasting from LiDAR via Future Object Detection

Forecasting from LiDAR via Future Object Detection 基础信息 论文&#xff1a;cvpr2022paper https://openaccess.thecvf.com/content/CVPR2022/papers/Peri_Forecasting_From_LiDAR_via_Future_Object_Detection_CVPR_2022_paper.pdfgithub&#xff1a;https://github.co…

UWB透传模块-通信距离1KM UWB650 透明传输 | 双向测距 | 定位模块

UWB650模块是思为无线推出的一款基于UWB&#xff08;Ultra Wide Band&#xff0c;超宽带&#xff09;技术的无线通讯模块&#xff0c;遵循IEEE 802.15.4-2020 Standard协议。UWB650模块是在UWB3000F27基础上研发&#xff0c;使该模块拥有0.5W的高功率功放芯片。用户无需去设计电…

Ubuntu使用chkconfig命令时报错:chkconfig: command not found解决办法

文章目录 前言一、安装sysv-rc-conf1.1 引入库安装可能报错&#xff1a;E: Unable to locate package sysv-rc-conf1.2 添加镜像源后更新安装源&#xff1a;1.3 更新安装源可能报错如下内容&#xff1a;1.4 添加密钥1.5 添加密钥后更新安装源&#xff1a;1.6 用apt-get安装sysv…

能源企业的“宿命”,是成为穿越时代的传奇

2012年&#xff0c;杰里米里夫金的《第三次工业革命》出版&#xff0c;他在书中提出了能源互联网的观点&#xff0c;将互联网技术和可再生能源结合起来&#xff0c;用以支持未来的产业革命。 里夫金不愧是和凯文凯利&#xff08;KK&#xff09;齐名的未来学家&#xff0c;十几…

fastapi swagger在线接口文档报错

fastapi swagger在线接口文档报错 1、报错信息 Unable to render this definition The provided definition does not specify a valid version field. Please indicate a valid Swagger or OpenAPI version field. Supported version fields are swagger: “2.0” and those …

Python笔记 json数据格式的转换

一、json数据格式 1.什么是json json是一种轻量级的数据交互格式。可以按照json指定的格式去组织和封装数据 json本质上是一个带有特定格式的字符串 主要功能&#xff1a;json就是一种在各个编程语言中流通的数据格式&#xff0c;负责不同编程语言中的数据传递和交互。类似…

Windows电脑自建我的世界MC服务器并与好友远程联机游戏教程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

红海云签约茉莉奶白,引领茶饮行业人力资源数字化新潮流

关于茉莉奶白 茉莉奶白&#xff0c;始于深圳&#xff0c;以茉莉为首的东方四白花为灵感&#xff0c;择高山茗茶以花窨之法制茶&#xff0c;专注茉莉香中国茶。一直坚持对茉莉的极致探索&#xff0c;从视觉到味蕾完美诠释东方摩登。让现代年轻人在日常中感知东方花道与茶道的魅力…

函数创建单链表---无n型,需要 while 循环 + scanf

题目&#xff1a; #include <stdlib.h> struct link{int data;struct link *next; }; struct link* creatLink(); int main(){struct link *head,*p;headcreatLink();for(phead->next ;p;pp->next )printf("%d ",p->data );return 0; }/* 请在这里填…

图像基础知识入门【图像概念不同图像格式】

图像基础知识入门【图像概念&不同图像格式】 最近有在处理图像转换&#xff0c;因此稍微补足了一下图像相关知识&#xff0c;特在此记录。下面汇总是我根据自己理解和网上查阅资料而来。如有错误&#xff0c;欢迎大家指正。 1 基础概念 像素/分辨率 像素(Pixel)&#xff…