Privilege escalation via the unintended UnattendedUtilities

栏目: IT技术 · 发布时间: 3年前

内容简介:The ‘UnattendedUtilties’ is a Windows Runtime class object that is registered within the XboxDevService.exe residing in the Xbox One’s SRA partition. This service is only registered and executed when an authorized Xbox One is running under Developer Mode a

The ‘UnattendedUtilties’ is a Windows Runtime class object that is registered within the XboxDevService.exe residing in the Xbox One’s SRA partition. This service is only registered and executed when an authorized Xbox One is running under Developer Mode and will not execute in a retail environment. Initially, this was discovered after noticing an addition in the ‘Dev Home’ application file list that featured a tool section named ‘unattend’ which featured the tool page’s script as well as *.xboxunattend files located on the System Tools drive. Viewing these *.xboxunattend files revealed that they were simply batch scripts with a renamed extension.

Privilege escalation via the unintended UnattendedUtilities

Privilege escalation via the unintended UnattendedUtilities

Oddly, almost none of these pages are actually available in standard UWA developer mode. They do not appear in app during runtime at all. Are these hidden intentionally? And do they still work?

Upon inspection of the Dev Home findings, it contained an interesting set of code:

// Copyright (c) Microsoft Corporation. All rights reserved.
_runScriptOnUsb: function () {
    try {
         // Disable the button to prevent pressing it multiple times.
        this._runScriptOnUsbButton.disabled = true;
        this._closeConfigureUnattendButton.focus();

        unattendUtils.runUnattendedScriptOnUsbAsync();
    } catch(e){
        // Do nothing. This shouldn't normally fail but can if the user removes the USB
        // drive at the right time.
    }
},

The code that stands out is certainly ‘unattendUtils.runUnattendedScriptOnUsbAsync()’ which peaked my interest as I was curious to whether these “scripts” were executed based on the calling application or whether or not it was a system service. Next, I peaked around for where the function belonged which was a simple task - the namespace that ‘unattendUtils’ referred to was ‘Microsoft.Xbox.Development.UnattendedUtilities’. Conventiently, in the root directory of the Dev Home application there was a ‘microsoft.xbox.development.winmd’ file there! Of course, if you are already familiar, this is a Windows Metadata file used by the Windows Runtime system that contains the information for the interfaces that reside in another process.

These file types can simply be dropped in a .NET Disassembler (e.g. JetBrains dotPeek) with the ability to view the class definitions as well as other types.

Privilege escalation via the unintended UnattendedUtilities

Hah! We have an already defined interface with some interesting functions. But due to the nature of these Windows Metadata files meant that the host binary was separate than Dev Home. This can very easily be discovered, however, as there are usually ‘ProxyStubs’ that are loaded into client-calling applications when said application creates an instance of a class object. By debugging the Dev Home app remotely, we can look at the loaded modules and determine which may be responsible. As we were running in developer mode, I suspected it only had to be related to a limited subset of executables and therefore when finding ‘XboxDevService.ProxyStub.dll’ loaded in the Dev Home process I immediately decided to disassemble the server itself.

Reversing XboxDevService

As these scripts appeared to simply be batch scripts, I figured that the XboxDevService would require to call the ‘CreateProcess’ API, I viewed the executable imports and xref’d the CreateProcessW import until I came across a function that most definitely provided enough basis that this service was responsible.

sub_1400238B8

hInput = GetStdHandle(0xFFFFFFF6);
targ_handle = hTarget;
lpCmdLine = WindowsGetStringRawBuffer(scriptPath, 0); // scriptPath from function parameter (a2)
v31 = (__int64) & v31;
// Execute script via full path
if ((unsigned int) CreateProcessW(0, lpCmdLine, 0, 0, 1, 0x8000000, 0, & startupInfo, & lpProcInfo))
  goto LABEL_84;
dwLastError = GetLastError();
res = (unsigned __int16) dwLastError | 0x80070000;

// ...

// Create string reference with message for toast notification
if ((int) WindowsCreateStringReference(L "See SystemScratch\\boot\\logs directory for the log file.", 55, & hSTR_HDR_LOG_DIR, & hSTR_LOG_DIR) < 0)
  RaiseException(0xC000000D, 1, 0, 0);
hSTR_LOG_DIR_2 = hSTR_LOG_DIR;
if ((int) WindowsCreateStringReference(
    L "Unattended script complete.",
    27, &
    hSTR_HDR_COMPLETE_MSG, &
    HSTR_CLASS_FRONTPANEL_UTILS) < 0) {
  RaiseException(0xC000000D, 1, 0, 0);
  res = CreateToast(HSTR_CLASS_FRONTPANEL_UTILS, hSTR_LOG_DIR_2, v25, v24);
  if (res >= 0) {
    classObject = 0;
    // Create string reference containing the activatable class id
    if ((int) WindowsCreateStringReference(
        L "Microsoft.Xbox.Development.FrontPanelDisplayUtilities",
        53, &
        hSTR_HDR_COMPLETE_MSG, &
        HSTR_CLASS_FRONTPANEL_UTILS) < 0)
      RaiseException(0xC000000D, 1, 0, 0);
    hClassId = HSTR_CLASS_FRONTPANEL_UTILS;
    v28 = classObject;
    if (classObject) {
      classObject = 0;
      self_ret( * (__int64( ** )(void))( * (_QWORD * ) v28 + 16));
    }
    // Register Windows Runtime object
    res = RoGetActivationFactory(hClassId, & IID_FrontPanelDisplayUtilities, & classObject);
    if (res >= 0) {
      pFrontPanelDisplayUtils = classObject;
      // Create string reference with message for front panel
      if ((int) WindowsCreateStringReference(
          L "Unattended script complete.",
          27, &
          hSTR_HDR_COMPLETE_MSG, &
          HSTR_CLASS_FRONTPANEL_UTILS) < 0)
        RaiseException(0xC000000D, 1, 0, 0);
      res = self_ret( * (__int64( ** )(void))( * (_QWORD * ) pFrontPanelDisplayUtils + 96)); // ShowFrontPanelNotification(msg)
    }
    // ...
  }
  // ...
}
}

The pseudo-code allows us to draw conclusions that this particuluar function is one that is responsible for executing unattended scripts as it provides the way for popping a toast notification, and for chuckwalla kits it will use the front panel, while referring to the log output directory. By determining the host process of the Windows Metadata we located earlier, we can now begin attempting to create an instance of the class ‘UnattendedUtilities’ and attempt to execute our own script. I searched around online and also the Windows SDK for references to how Windows Runtime classes are usually specified and came across several resources outlining the class definitions but I was still unsure. So, I decided to look around for other binaries which may rely on the UnattendedUtilities class - which was the Windows Device Portal. This lead me down a path of manually defining the interface with stubs to ensure the correct offsetting…

Privilege escalation via the unintended UnattendedUtilities

which I quickly discovered utilities provided in the Windows SDK which does the hardwork for me.

Article: How to: Use winmdidl.exe and midlrt.exe to create .h files from windows metadata

By running via the Visual Studio Developer Prompt:

winmdidl.exe /nologo /outdir:"output" microsoft.xbox.development.winmd
midlrt.exe microsoft.xbox.development.unattendedutilities.idl /metadata_dir "C:\Windows\System32\WinMetadata"

This generates a header file that defines all that we need. It’s… a mess so I decided to tidy up the results and neatly define what we need.

MIDL_INTERFACE("DE87AD07-75DC-4EEC-9226-5628E98B9914")
IUnattendedUtilitiesStatics : public IInspectable
{
public:
	virtual HRESULT STDMETHODCALLTYPE RemoveUnattendedScript(void) = 0;
	virtual HRESULT STDMETHODCALLTYPE RetrieveUnattendedScript(void) = 0;
	virtual HRESULT STDMETHODCALLTYPE RetrieveAndRunUnattendedScriptAsync(void) = 0;
	virtual HRESULT STDMETHODCALLTYPE RetrieveAndRunUnattendedScript(HRESULT* scriptResultHr, HSTRING* scriptOutput) = 0;
	virtual HRESULT STDMETHODCALLTYPE RunUnattendedScript(HSTRING scriptFileFullPath, HSTRING logFileFullPath, HRESULT* scriptResultHr, HSTRING* scriptOutput) = 0;
	virtual HRESULT STDMETHODCALLTYPE AbortUnattendedScript(void) = 0;
	virtual HRESULT STDMETHODCALLTYPE SendToastNotification(HSTRING title, HSTRING message) = 0;
	virtual HRESULT STDMETHODCALLTYPE IsScriptRunning(boolean* isRunning) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldRunOobeScript(boolean* shouldRun) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldRunOobeScript(boolean shouldRun) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldBlockUsbScripts(boolean* shouldBlock) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldBlockUsbScripts(boolean shouldBlock) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldSkipAbortToast(boolean* skip) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldSkipAbortToast(boolean skip) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldCallDevCenter(boolean* shouldCall) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldCallDevCenter(boolean shouldCall) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldBlockUnattendScripts(boolean* shouldBlock) = 0;
	virtual HRESULT STDMETHODCALLTYPE ShouldBlockUnattendScripts(boolean shouldBlock) = 0;
	virtual HRESULT STDMETHODCALLTYPE ScriptRunningChanged(int64_t* handler, EventRegistrationToken* token) = 0;
	virtual HRESULT STDMETHODCALLTYPE ScriptRunningChanged(EventRegistrationToken token) = 0;
	virtual HRESULT STDMETHODCALLTYPE HasUnattendedScriptOnUsb(boolean* hasScript) = 0;
	virtual HRESULT STDMETHODCALLTYPE RunUnattendedScriptOnUsbAsync(void) = 0;
};

Did it work?

After putting together a small console program and simply using the ‘RetrieveAndRunUnattendedScriptAsync()’ function, I wrote a script that would run telnet and created a console notification to signal a more obvious result. Once deployed and connected over via SSH, I plugged in my USB with the specified script, opened up the Xbox Device Portal for monitoring processes and then executed my program…

Privilege escalation via the unintended UnattendedUtilities

Suddenly, on my console I see something!

Privilege escalation via the unintended UnattendedUtilities

Success!

Now to double check on the device portal…

Privilege escalation via the unintended UnattendedUtilities

YES! We have successfully ran an unattended script and also achieved the highest privilege level! Once there is a telnet instance running at the highest privilege level, we can utilise the ‘net1.exe’ carried over from a Windows Core build and add a new user with an administrator role and also enable the built-in administrator account. These accounts will persist across reboots in developer mode as long as you avoid clearing the data when switching back to retail.

Privilege escalation via the unintended UnattendedUtilities

Utilising the UnattendedUtilities allowed us to elevate our existing user privileges within the SRA partition which also grants more flexibility and access to continue researching and reverse engineering the operating system. So why the big deal? It mostly comes down to a combination of how the developer mode works and from experience reporting and dealing with these issues in the past. Developer Mode itself relies on a certificate that is either authorized by Xbox Live, if you are a partner or UWA developer, or an internal Microsoft developer. These certificates contain console specific information and capabilities.

There are different capabilities that generally depend on what type of “devkit” you have; even though it is dependent on what the certificate says. We have:

  • ERA - For game development - offering a much wider range of tools and access
  • SRA (Now UWA) - For app development specifically targeting the System OS - much more limited in scope.
  • Internal - For consoles that are used for OS and Security development at Microsoft

The point to note down here is that UWA is completely lacking the range of tools featured as an ERA kit. While this makes sense, it is interesting that the features leftover, which generally check which mode and devkit type the console is before executing, actually work and ignore the context without official public documentation and tooling.

You can read more information at the Xbox One Research Wiki .

Disclosure

Since the feature was hidden away and after doing some investigating it was understood that the ‘unattend’ feature was meant for use on ‘ERA’ authorized development kits and was documented on the Xbox One XDK. As the feature worked on UWA I had responsibly put together a PoC and small write up and notified MSRC. However, the response was not what I was expecting as they claimed that it was ‘by design’ and is an intended feature for developer mode. Despite being hidden away and not accessible, it’s intended. This result was quite surprising as they had been quick previously to fix other issues that allowed privilege escalation but I welcome the new approach.

With the locked away features being a bit of a pain to get working successfully I decided to publicly release my program to enable more than myself, and team, to put the privileges to use and hopefully see individuals doing their own research.

You can find the XboxUnattend project here .

Timeinline

  • 20/09/2018 - Initial discovery
  • 16/05/2019 - Proof-of-Concept and write-up
  • 17/05/2019 - Sent MSRC said PoC and write-up
  • 20/05/2019 - Initial response from MSRC
  • 22/05/2019 - MSRC confirmed it was ‘by-design’
  • 10/09/2019 - Disclosed PoC publicly on GitHub

P.S

Privilege escalation via the unintended UnattendedUtilities


以上所述就是小编给大家介绍的《Privilege escalation via the unintended UnattendedUtilities》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C#图解教程

C#图解教程

索利斯 / 苏林、朱晔 / 人民邮电出版社 / 2009-1 / 65.00元

本书是一本广受赞誉的C# 教程。它以图文并茂的形式,用朴实简洁的文字,并辅之以大量表格和代码示例,精炼而全面地阐述了最新版C# 语言的各种特性,使读者能够快速理解、学习和使用C#。同时, 本书还讲解了C#与VB 、C++ 等主流语言的不同点和相似之处。 本书是一本经典的C# 入门书,不仅适合没有任何编程语言基础的初级读者,而且还是有VB 、C++ 等语言基础的C# 初学者的最佳选择。一起来看看 《C#图解教程》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具