首页
社区
课程
招聘
[原创]银狐远控后台桌面实现原理详解(一)
发表于: 1天前 431

[原创]银狐远控后台桌面实现原理详解(一)

1天前
431

图片


银狐的一共提供了4个远程桌面功能,其中差异屏幕高速屏幕后台屏幕,前三种屏幕都是正常的屏幕截图技术,只不过在屏幕数据传输大小和渲染效率上做了不同的取舍,而后台屏幕不是正常的屏幕,它是一个限制了很多正常界面操作的不可见桌面,虽然对被控者不可见,但聪明的开发者们利用特殊的绘制技巧让它对控制者可见,并能进行一部分的操作。

图片


最终效果就是,假设你的电脑被控制了,控制者在你的电脑上新开了一个桌面,可以进行相关的鼠标和键盘操作,但是你却看不到,是不是很可怕?实际上,它没想象中那么可怕,但也容易被利用。所以:


特别申明:

  1. 本文介绍的内容仅做技术上的交流,请勿使用本文介绍的技术做其他用途,违者与本号无关。

  2. 作者不提供任何支持生成可用shellcode和免杀版本的银狐源码,有此需求的读者请勿联系作者,只接受网安(带有效证件)相关的技术交流和合作,黑灰产勿扰。

银狐的后台屏幕功能完全照抄开源HVNC项目,如果你不了解Windows的一些机制,即使去阅读这些代码,你可能也很难读懂。所以后台桌面功能我们分为两篇来讲解,这是第一篇,我们来讲解技术原理,了解了技术原理之后,第二篇讲解具体的实现代码时,就容易读懂代码了。

一、Windows桌面的概念

当我们使用 Windows 电脑时,总会看到一个被称为“桌面”的区域,上面排列着文件和文件夹的图标。

事实上,存在一个通常不可见的“隐藏桌面”,它可能正被恶意利用。简而言之,Windows 操作系统提供了一种机制,允许您在默认桌面(也称为“默认桌面”)之外创建新的桌面。但是,普通用户无法轻松创建新桌面。您必须通过调用程序内部用于创建新桌面的代码(Win32 API)来显式创建新桌面。有些软件会利用这种机制创建用户看不到的隐藏桌面。

在这个新创建的桌面世界中,您可以像往常一样打开文件和文件夹并运行应用程序,但它不会出现在我们通常看到的默认桌面世界中。这意味着攻击者可以利用恶意软件感染用户的电脑,并使用该恶意软件在用户的电脑上创建一个新的桌面,然后在该桌面上执行恶意操作,而用户甚至不会察觉。

二、Windows操作系统中的桌面及其结构

使用Windows操作系统时,我们每天都会用到一个名为“桌面”的东西,而我们却很少意识到它的存在。这里指的是电脑启动时显示的图标和壁纸,也就是我们熟悉的桌面界面。

事实上,这个桌面系统的结构出乎意料地复杂,其整体结构(概要)如下:

图片

我们通常看到的桌面是名为“Default”的桌面,它位于名为“Session 1”的结构中的名为“WinSta0”的 WindowStation 结构中(准确地说,分配了一个大于 1 的数字)。

如上图所示,桌面并非只有一个。默认情况下存在一些特殊桌面,例如登录屏幕和屏幕保护程序桌面,您也可以手动创建新的桌面。例如,当您尝试运行需要管理员权限的程序时,熟悉的“UAC”(用户帐户控制)屏幕会变黑,而这个屏幕实际上就是一个名为“Winlogon”的特殊桌面。

新建的桌面是一个空白的屏幕,没有图标和任务栏,只有壁纸。这是因为资源管理器 (Explorer.exe) 没有运行。启动 Explorer.exe 后,图标和任务栏就会像在普通桌面上一样显示出来。

启动资源管理器后,您可以像在普通桌面电脑上一样打开文件和文件夹并显示窗口,并以与普通桌面电脑相同的方式使用它。

图片

那么,究竟该如何创建一个新的桌面呢?

事实上,目前没有默认方法可以让用户轻松创建此类对象。

您需要使用 Win32API(Windows 函数)编写程序,或者使用外部免费工具。

以编程方式操作桌面时主要使用的 Win32API 如下:

  • 调用CreateDesktop创建新桌面

  • 使用SetThreadDesktop将新桌面绑定到你的线程

  • 使用SwitchDesktop切换桌面


特别申明:

  1. 本文介绍的内容仅做技术上的交流,请勿使用本文介绍的技术做其他用途,违者与本号无关。

  2. 作者不提供任何支持生成可用shellcode和免杀版本的银狐源码,有此需求的读者请勿联系作者,只接受网安(带有效证件)相关的技术交流和合作,黑灰产勿扰。

本质上,您可以使用 CreateDesktop 函数创建一个新桌面,并且可以通过调用 SwitchDesktop 函数以编程方式切换活动桌面。

如果您想在不使用免费工具的情况下创建和使用新的桌面,则需要使用这些 Win32API 编写程序。但是,这需要谨慎处理,因为如果您忘记添加在切换到新桌面后返回原始桌面的代码,则在重启电脑或注销之前,您将无法再次返回原始桌面。

但是,各个桌面之间存在一个限制,即您无法枚举(查看)每个桌面中创建的窗口(见下图)。

图片

也有一些威胁会利用这一点。例如,即使攻击者通过 HiddenVNC (hVNC)(网上银行恶意软件使用的软件)在用户的隐藏桌面上打开各种窗口,通常也无法从原始桌面(使用工具等)枚举这些窗口(尽管可以干扰进程)。

一般来说,Windows Station 与进程绑定,而 Desktop 与线程绑定。

换句话说,在典型的应用程序中,新创建的窗口(非模态窗口:允许您在不关闭顶部显示的窗口的情况下操作同一应用程序的其他窗口的窗口)是作为单独的线程生成的,因此在“桌面 1”上启动的进程可以在“桌面 2”上创建一个新窗口(线程)。

至于为什么 Windows 没有为普通用户提供便捷的桌面扩展系统,尽管 MSDN 发布了一系列用于创建新桌面(扩展桌面)的 Win32API,但这只是猜测。或许 Windows 的目的是为了让开发者能够开发各种用途的应用程序,例如允许用户在商店的电脑上仅访问特定应用程序,或者创建能够显示与常规桌面隔离的窗口的游戏。( Windows 10 有一个类似的功能,称为虚拟桌面,用户可以轻松使用。)

以上我们解释了Windows操作系统中桌面的结构和机制。

在接下来的章节中,我们将介绍并解释利用这些机制的一个案例。

三、桌面威胁案例1——如何创建和使用新的桌面来显示信息

这里我们将以国外名为“Tyrant”的勒索软件为例,解释它的工作原理。

当 Tyrant 感染计算机时,它会执行以下操作来创建一个新的桌面:

  • 首先,我们使用名为 GetThreadDesktop 的 Win32 API 临时保存(备份)当前桌面的配置信息。接下来,我们使用 CreateDesktop 创建一个新桌面。由于这只是在现有桌面之后创建一个新桌面,因此我们需要使用 SwitchDesktop 激活新创建的桌面,并使用 SetThreadDesktop 将当前程序的线程与新创建的桌面关联起来。

伪代码如下:

// 临时保存当前的桌面
IntPtr threadDesktop = WinAPI.GetThreadDesktop(WinAPI.GetCurrentThreadId());

// 创建名为“HAHA”的桌面
IntPtr hNewDesktop = WinAPI.CreateDesktop("HAHA", IntPtr.Zero, IntPtr.Zero, 0, 512, IntPtr.Zero);

try
{
    // 激活创建的新桌面
    WinAPI.SwitchDesktop(hNewDesktop);

    bool workdone = false;
    BackgroundWorker backgroundWorker = new BackgroundWorker();
    backgroundWorker.DoWork += delegate
    {
        // 将当前线程关联到新桌面
        WinAPI.SetThreadDesktop(hNewDesktop);       
    };
}

这一系列操作将激活一个由“Tyrant”控制的新桌面。

Tyrant随后创建并显示一个带有威胁信息的窗口。

图片

综上所述,用户看到的桌面(以下简称活动桌面)如下所示:

图片

此时,屏幕上会出现一个显示“Tyrant”威胁窗口的新桌面,用户将无法再访问原来的桌面。(如上所述,新创建的桌面不会运行 Explorer.exe,因此不会显示图标或任务栏。)

在这种情况下,“Tyrant”的主进程将保留在原来的默认桌面上,而上面显示的威胁屏幕将是“Tyrant”主进程创建的“窗口”。

这基本上可以归结为如下技术流程:

图片

如上图所示,“Tyrant”创建的窗口跨越多个桌面,由于上文所述的桌面限制,无法从默认桌面枚举“Tyrant”恐吓屏幕的窗口信息。这意味着,例如,它可以绕过那些使用窗口信息进行恶意检测的安全产品。

Tyrant 使用的这种扩展型桌面勒索技术对攻击者有以下优势(对用户有以下劣势):

  • 首先,新桌面上没有任何显示,因此无法启动调查工具和应用程序(由于资源管理器未运行,无法打开文件和文件夹)。这最大限度地减少了用户对自身操作的控制,同时仍然允许用户在勒索屏幕上自由使用鼠标和输入键盘,同时也允许攻击者执行必要的用户操作,例如联系用户索要款项。

  • 此外,即使安全软件成功清除了勒索软件,也必须重启电脑才能恢复原始桌面。因为程序创建的桌面即使关闭也不会消失,所以除非显式调用恢复默认桌面的进程,否则无法恢复原始桌面,这可能会给用户造成困扰。

再次强调,从调查人员的角度来看,即使存在能够枚举默认桌面窗口的工具,也无法枚举(理解)此勒索软件(屏幕锁定程序)的窗口。这是因为,正如上文所述,不同桌面之间无法访问彼此的窗口信息,这是一项限制。

四、桌面威胁案例2 - 网上银行恶意软件案例(隐藏的 VNC)

另一种利用新建桌面电脑的重大威胁是网上银行恶意软件。这类恶意软件会隐藏在受感染的电脑中,伺机在用户尝试使用网上银行服务时执行未经授权的操作,例如窃取密码和ID等登录信息。许多类型的网上银行恶意软件都使用名为HiddenVNC (hVNC) 的恶意模块(组件)来远程控制受感染的电脑。(注:HiddenVNC 是一个恶意模块,它是由合法的开源远程控制软件“VNC”修改而来,与普通的VNC不同。)

使用普通的VNC(远程控制软件),鼠标和窗口的移动会在远程控制器和远程操作者之间同步,这使得远程控制计算机的行为显而易见。然而,使用名为HiddenVNC (hVNC)的模块,即使远程操作者打开窗口或启动程序,远程操作者的屏幕上也不会显示任何变化。这意味着,受感染的计算机可以被远程控制,而用户却毫不知情。本文的重点——隐藏桌面机制——正是在此发挥作用。

图片

使用 HiddenVNC (hVNC) 的攻击基本流程如下:首先,攻击者先用网上银行恶意软件感染目标计算机,然后再用 HiddenVNC (hVNC) 感染该计算机。这会导致 HiddenVNC (hVNC) 在受感染的计算机上创建一个新的桌面(隐藏桌面)。然后,HiddenVNC (hVNC) 会尝试连接到攻击者端(操作工具端)。一旦连接建立,攻击者就可以随意操作;无论他们在隐藏桌面上打开多少文件或程序,都不会影响默认桌面,用户也不会察觉。

图片

HiddenVNC 最具威胁性的使用场景之一是用户使用浏览器时。这是因为即使在不同的桌面上,同一浏览器的登录会话也可以共享。例如,假设用户像往常一样使用默认桌面上的浏览器访问一个需要登录的网站。与此同时(假设该网站已被 HiddenVNC 感染),攻击者可以在隐藏的桌面上启动相同类型的浏览器(例如 IE)并访问同一网站。这样,攻击者无需知道(或输入)登录 ID 或密码即可登录该网站。

测试发现,使用2013年左右的旧版HiddenVNC时,大多数主流浏览器都采取了相应的反制措施,导致无法在两个桌面上同时启动同一个浏览器。然而,使用2016年之后开发的较新版HiddenVNC时,除了Edge浏览器外,所有主流浏览器都能够成功地在默认桌面和隐藏桌面上同时启动同一个浏览器。此外,还证实了在国内一些用户众多的大型网站上,登录会话是可以共享的。

图片

使用这种方法时,就不再是恶意软件在交易过程中进行干预的恶意活动(例如中间人攻击,它会将恶意代码注入浏览器),这种情况下很容易区分用户和攻击者;它本质上与有人手动操纵用户的浏览器相同,几乎无法一眼区分用户和攻击者,因此很难准确地将他们区分开来。

以下是 HiddenVNC (hVNC) 的部分代码,该程序被网上银行恶意软件等使用。这段代码是 HiddenVNC (hVNC) 在受感染的电脑(即用户端)上创建隐藏桌面的核心。

以下来自 HiddenVNC (hVNC) 的代码会在受感染的电脑上创建一个新的桌面,并在该桌面上启动 Explorer.exe 进程。显然,Explorer 进程是被显式启动的,因为只有在桌面上运行 Explorer 时才能进行远程文件操作。这表明 HiddenVNC (hVNC) 的开发者意图通过远程控制 Explorer 来实现文件操作。

此外,由于在使用 CreateDesktop 函数创建新桌面后,SwitchDesktop 函数根本没有被调用,因此活动桌面不会改变,用户也对此毫不知情。换句话说,用户根本无法察觉到这些操作正在执行。

HiddenVNC (hVNC) 中创建隐藏桌面的伪代码如下:

// 持有HVNC服务器的桌面句柄 || HVNC服务器的资源管理器进程ID已存在 || HVNC服务器的资源管理器进程ID对应的进程仍存在
elseif ((hDesktop->hDesktop) || (lpServer->dwExplorersPID) || (IsProcess(lpServer->dwExplorersPID)))
{
    // 创建新的桌面
    if (lpServer->hDesktop = CreateDesktopA(
        lpServer->DeskInfo.szDeskName,
        NULL,
        NULL,
        DF_ALLOWOTHERACCOUNTHOOK,
        GENERIC_ALL,
        NULL))
    {
        if (!lpServer->hDesktop)
            return FALSE;

        // 将当前线程关联到新建的桌面
        SetThreadDesktopEx(lpServer->hDesktop);
        lpServer->WndInfo.hDeskWnd = GetDesktopWindow();

        // 若HVNC服务器的桌面配置标志中未设置NOBITBLT标志
        if (!(lpServer->DeskInfo.dwFlags & HUNC_NOBITBLT))
            StartWatcher(lpServer);

        // 若HVNC服务器的桌面配置标志中未设置NO_SHELL(不加载壳程序)标志
        if (!(lpServer->DeskInfo.dwFlags & HUNC_NO_SHELL))
        {
            PROCESS_INFORMATION pi = { 0 };
            STARTUPINFOA siInfo = { 0 };
            siInfo.cb = sizeof(siInfo);
            // 指定创建进程时关联的桌面名称
            siInfo.lpDesktop = lpServer->DeskInfo.szDeskName;

            // 创建资源管理器(Explorer)进程
            if (!CreateProcessA(
                lpServer->Names.szShell,
                NULL,
                NULL,
                NULL,
                false,
                0,
                NULL,
                NULL,
                &siInfo,
                &pi))
                return FALSE;

            // 将进程ID保存为HVNC服务器的资源管理器进程ID(全局+本地双赋值)
            lpServer->lpGlobalWndData->dwExplorersPID = lpServer->dwExplorersPID = pi.dwProcessId;
        }
    }
}

特别申明:

  1. 本文介绍的内容仅做技术上的交流,请勿使用本文介绍的技术做其他用途,违者与本号无关。

  2. 作者不提供任何支持生成可用shellcode和免杀版本的银狐源码,有此需求的读者请勿联系作者,只接受网安(带有效证件)相关的技术交流和合作,黑灰产勿扰。

此外,当使用 HiddenVNC (hVNC) 远程控制 PC 时,会使用隐藏的桌面,因此被控制的屏幕对用户不可见。

那么,为什么连接到感染了 HiddenVNC (hVNC) 的电脑上的设备的鼠标和键盘操作不受影响呢?即使可以使用隐藏桌面来隐藏窗口移动,鼠标光标和其他设备也是共享的,在远程控制电脑时,它们的移动应该与攻击者的操作同步。

事实上,这就是鲜为人知且复杂的 HiddenVNC (hVNC) 技术发挥作用的地方。

五、为什么可以在不移动鼠标的情况下远程控制计算机且显示后台桌面画面?

总之,HiddenVNC (hVNC) 使用了一种技术,可以在不移动受感染电脑上的鼠标光标的情况下,模拟受感染电脑上的鼠标光标操作结果。

例如,假设攻击者将鼠标移到 VNC 查看器上并单击某个位置。

HiddenVNC (hVNC) 首先获取攻击者发送的鼠标点击坐标 (aX, aY),并将其转换为用户电脑隐藏桌面上的坐标 (bX, bY),转换过程中会考虑受感染设备的屏幕尺寸等因素。然后,它使用 PostMessage 函数向这些坐标发送点击事件(表示点击的命令)。这会导致 Windows 操作系统将该事件解释为鼠标实际点击了这些坐标,并继续执行后续操作。

图片

让我们仔细看看 HiddenVNC 相关部分的源代码,看看它实际是如何工作的。

以下是 HiddenVNC 源代码中的一段摘录,该摘录与攻击者在其 PC 上操作的鼠标左键或右键点击事件作为点击事件发送到受感染 PC 上的 HiddenVNC (hVNC) 部分有关。

WPARAM wParam=0;

// 鼠标左键被点击时
if (wMsg == WM_LBUTTONDOWN)
    wParam=WM_TBLCLOCK;
// 鼠标右键被点击时
elseif (wMsg == WM_RBUTTONDOWN)
    wParam=WM_RBCLICK;

// 发送点击事件
if ((lpServer->WndsInfo.hToolBarWnd) && (wParam))
{
    // 坐标信息
    PostMessage(lpServer->WndsInfo.hToolBarWnd, lpServer->lpGlobalWndData->dwVNMessage, wParam, dwClientCursorPos);
}

// 排除桌面图标和任务栏等的窗口
hTopLevel=lpServer->MstateInfo.hLastTopLevelWnd;
if ((bP) || (hTopLevel != lpServer->WndsInfo.hTrayWnd) && (hTopLevel != lpServer->WndsInfo.hStartBtnWnd))
    hTopLevel=lpServer->lpGlobalWndData->hForegroundWnd;

// 指定前台窗口
if ((hWndParent != hTopLevel) && (!GetWindowClassFlags(lpServer, hWndParent) & WCF_NO_CAPTURE))
{
    
}

除了上述功能外,我们还模拟了双击和拖放等多次点击事件。

HiddenVNC还有许多其他设计非常精良的功能。

让我来介绍另一种独特的机制。

乍一看,使用隐藏桌面进行非法操作似乎是隐藏某些内容的完美方法,但实际上屏幕传输存在局限性。这意味着 Windows 操作系统有一种机制,不会绘制用户不可见的屏幕区域。例如,如果两个窗口重叠,重叠的隐藏窗口区域实际上不会在背景中绘制。隐藏桌面也是如此;无法对隐藏桌面(即用户不可见的区域)进行屏幕截图(捕获)或传输屏幕(如果您尝试截屏,屏幕将一片漆黑)。因此,即使您尝试使用普通的 VNC 远程控制隐藏桌面,也无法捕获屏幕,也无法继续进行操作。

图片

如果看不到对方的屏幕,远程控制就无法继续进行。因此,HiddenVNC 的开发者们想出的解决方案是:对隐藏桌面上创建的每个窗口调用 PrintWindow 函数(该函数用于获取窗口绘制信息),然后根据桌面的 Z 轴顺序,将单独获取的窗口图像(绘制信息)叠加起来,从而重建整个屏幕的图像,实现通常情况下无法实现的屏幕传输。因此,在 HiddenVNC 实际传输的屏幕上,每个窗口都是单独绘制的,所以可以看到每个窗口都在细微地重绘,并伴有闪烁。

图片

开发人员的敬业精神显而易见,他们成功地创建了如此复杂的流程,以至于感觉就像操作系统从零开始创建了桌面绘图流程一样。

老实说,这种技术挺复杂的,且不为一般人员所知,所以,请务必遵守国家相关法律法规,合理使用技术。

六、最后

至此,我们解释了 Windows 桌面的机制以及银狐实现后台桌面的技术原理。是不是感觉Windows桌面系统比想象的要复杂得多?

话又说回来,即使恶意软件在电脑上创建了“隐藏桌面”,普通用户也无法得知;此外,从安全人员的角度来看,目前能够查看电脑上非默认桌面的工具并不多。

下一篇文章中我将展示开发一个能显示进程列表及其使用的桌面信息的工具,有兴趣的可以关注一下。


更多阅读


银狐远控问题排查与修复——Viusal Studio集成Google Address Sanitizer排查内存问题

银狐远控代码中差异屏幕bug修复

银狐远程屏幕内存优化方法探究

银狐远程软件bug修复记录 第03篇

银狐远程软件 UDP 断线无法重连的bug排查和修复

银狐远程软件代理映射功能优化思路分享

银狐远程软件去后门方法

银狐远控一键编译调试与开发教程

银狐远控免杀与shellcode修复思路分析 01

银狐ShellCode混淆怪招

详解银狐远控源码中那些C++编码问题

给银狐远控增加一个小功能01


银狐远控的被控端是如何隐藏和保护自己的


从银狐复制和转移客户功能的bug说起......


谈几点银狐源码学习感悟


客户端软件的结构设计思考(一)——以银狐主控为例


由于银狐远控,被*安找了



[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

收藏
免费 0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回