Speaker 1: Welcome to the deep dive. You give it some really
Speaker 1: interesting material here, focusing on Windows security internals and PowerShell.
Speaker 2: Yeah, it's a great combination to look at.
Speaker 1: So that's our focus today. Our mission really is to
Speaker 1: pull out the core ideas, give you a shortcut to
Speaker 1: understanding how Windows handles security management and how PowerShell fits
Speaker 1: in as well, like an investigative.
Speaker 2: Tool, right without getting totally lost in the weeds. There's
Speaker 2: a lot of detail in these sources exactly.
Speaker 1: We're aiming for those aha moments, you know, finding the
Speaker 1: surprising bits about Windows security that PowerShell helps uncover.
Speaker 2: And what's really cool is how the sources link these
Speaker 2: like abstract security concepts directly to practical PowerShell commands.
Speaker 1: So it's not just theory, not at all.
Speaker 2: We'll actually see how PowerShell can light up the internals.
Speaker 1: Okay, let's dive in. The material starts by emphasizing setting
Speaker 1: up a PowerShell testing environment. Why is that the first
Speaker 1: crucial step.
Speaker 2: Well, it's super important because you need a safe place,
Speaker 2: a sandbox, right to try out these commands without messing
Speaker 2: up your actual system.
Speaker 1: Makes sense, you don't want to break anything accidentally exactly.
Speaker 2: And the source talks about set execution policy. Think of
Speaker 2: that as your first safety net stops accidental script running.
Speaker 1: Which can be a security risk in itself.
Speaker 2: Oh definitely. And the key thing is that set scope
Speaker 2: current user option for.
Speaker 1: Keeping tests just within your user account.
Speaker 2: Right, isolated testing. If you want system wide changes, well
Speaker 2: that's different. You'd need admin privileges for that, and you
Speaker 2: wouldn't use the scope parameter.
Speaker 1: Then gotcha. And the source notes that some setups, like
Speaker 1: maybe open source PowerShell or newer server versions might already
Speaker 1: have remote signed as the default.
Speaker 2: Yeah, so it's always smart to just check first, know
Speaker 2: where you stand.
Speaker 1: Okay, Next up PowerShell language basics. For someone diving into
Speaker 1: this material, what are the foundational bits that really give
Speaker 1: you leverage here?
Speaker 2: The sources bring up a few key things special variables
Speaker 2: like null p TOBE for your current directory pobid that's.
Speaker 1: The PowerShell process idea itself.
Speaker 2: Yeah, exactly, and ORNA four for environment variables like EnEv
Speaker 2: windeer knowing innovator D is surprisingly useful for security scripting
Speaker 2: context matters.
Speaker 1: And the difference between single and double quotes crucial.
Speaker 2: Double quotes allow string interpolation.
Speaker 1: So variables get automatically substituted in right.
Speaker 2: Makes building dynamic commands way easier, no messy string joining
Speaker 2: single quotes. They treat everything literally good when you need
Speaker 2: that exact string.
Speaker 1: That interpolation is a huge time saver. The source also
Speaker 1: mentions creating objects a new object using a GID as
Speaker 1: an example.
Speaker 2: Yeah, basic object creation and the naming convention for commands
Speaker 2: verb noun like a get item.
Speaker 1: Seems designed to make things easier to find.
Speaker 2: It really does help. You can often guess command names
Speaker 2: and then parameters like megapath with get item, let you focus.
Speaker 1: The command so you can target specific.
Speaker 2: Things exactly, and we'll get to get member later. But
Speaker 2: think of that as your magnifying glass for figuring out
Speaker 2: what an object is and what you can do with it.
Speaker 1: Okay, so you have these basic tools, how do you
Speaker 1: learn to use them effectively? The source talks a lot
Speaker 1: about get help.
Speaker 2: Oh, get help is your best friend in PowerShell, seriously indispensable.
Speaker 1: What does it give you?
Speaker 2: The synopsis, the full syntax, detailed descriptions, and what's really
Speaker 2: handy is using wild cards for parameter.
Speaker 1: Names like the ubjet example to find parameters starting with.
Speaker 2: Objeck exactly and the example's parameter that's often the best
Speaker 2: part real world usage examples invaluable can't.
Speaker 1: Be practical examples. Okay, now, what about making your own
Speaker 1: PowerShell tools. The material covers functions. What's key there, Well.
Speaker 2: The basics are the function keyword, then your function name.
Speaker 2: It's good practice to stick to that verb noun convention
Speaker 2: even for your own stuff. Keeps things consistent, makes sense,
Speaker 2: and parameters defined in the tarum block. You can specify
Speaker 2: types like string name, but you don't have to. PowerShell's
Speaker 2: pretty flexible.
Speaker 1: What if you don't use param.
Speaker 2: Then any arguments you pass just end up in the
Speaker 2: arg's array. You access them by number, like ARGs dollars
Speaker 2: or r T one.
Speaker 1: So named parameters are just numbered arguments. Good flexibility. Okay.
Speaker 1: The deep dive then shifts to output. How PowerShell shows
Speaker 1: you stuff and how you can control it.
Speaker 2: Right, So, when a command runs and you don't assign
Speaker 2: the output to a variable, PowerShell steps in and tries
Speaker 2: to display it nicely, usually a table or a list.
Speaker 1: It guesses the best format.
Speaker 2: Kind of yeah, based on the object's properties, but you
Speaker 2: have control. Select object is key for picking just the
Speaker 2: properties you care about. Cuts down the noise.
Speaker 1: Nice and format list forces.
Speaker 2: It into a list view one property per line. Basically
Speaker 2: great when you want to see all the details for
Speaker 2: a single object rather than a wide table.
Speaker 1: And if you don't even know what properties are available,
Speaker 1: that's where get member comes in again, right with DJ
Speaker 1: type property.
Speaker 2: Exactly if pipe your command output to get member iban
Speaker 2: type property and boom, you get the full list of
Speaker 2: data points you can access on those objects. It's like asking,
Speaker 2: what can you tell me about yourself?
Speaker 1: The decoder ring analogy works. Yeah, and sort object to
Speaker 1: organize it, yep, sort.
Speaker 2: My name, my side by memory usage, whatever property you need.
Speaker 2: Brings order to the chaos.
Speaker 1: Okay, so you can view the data how you want
Speaker 1: in the console, but what about saving it?
Speaker 2: Exporting data out file is the straightforward way. Saves the
Speaker 2: text output just as you see it to a file,
Speaker 2: then get content reads.
Speaker 1: It back end and the symbol.
Speaker 2: That's just a shortcut for outfile, quick and easy. But
Speaker 2: for like structured data you might want and excel h
Speaker 2: that's where export csv comes in. Creates a proper comma
Speaker 2: separated value file, much better for spreadsheets or databases.
Speaker 1: And that not no type information parameter.
Speaker 2: Oh yeah, good catch that just stops PowerShell from Putting
Speaker 2: that extra halftag type information line at the top of
Speaker 2: the CSV makes it cleaner for other programs to read.
Speaker 1: Okay, good tip. We've covered a lot of PowerShell basics.
Speaker 1: Now the material shifts gears, heading down into the Windows
Speaker 1: kernel and its security role. This feels like the real
Speaker 1: deep dive part.
Speaker 2: This is where it gets really fascinating. Yeah. The kernel,
Speaker 2: that's the absolute core of the OS, where a fundamental
Speaker 2: security decisions.
Speaker 1: Happen, and the connection point is system calls exactly.
Speaker 2: System calls are the bridge the way user mode applications,
Speaker 2: the stuff we normally run talk to the privileged kernel
Speaker 2: mode where the OS does its heavy lifting and enforcement.
Speaker 1: The link between our apps and the OS's security core. Okay,
Speaker 1: the material is several key kernel subsystems. Can you give
Speaker 1: us the quick security relevance run down?
Speaker 2: Sure you've got The object manager manages all kernel objects,
Speaker 2: the basic building blocks. The io manager handles data moving
Speaker 2: in and out. Process and thread manager creates and manages
Speaker 2: running code. Memory manager controls memory use. Configuration manager that's
Speaker 2: the registry code integrity. Make sure only trusted code runs.
Speaker 1: A lot of managers.
Speaker 2: Yeah, and crucially for security, the Security reference monitor, the SRM.
Speaker 1: SRM sounds important, the ultimate gatekeeper.
Speaker 2: Maybe that's a good way to put it. The SRM
Speaker 2: is the kernel component that actually enforces security policy. It
Speaker 2: decides who gets access to what.
Speaker 1: How does it do that?
Speaker 2: It uses two key things mentioned right in your source,
Speaker 2: access tokens and security descriptors. Every process has an access
Speaker 2: token saying who it is. Every resource, like a file
Speaker 2: or registry key, has a security descriptor saying who's allowed
Speaker 2: to access.
Speaker 1: So the SRN compares the token.
Speaker 2: To the descriptor exactly when a process tries to access something,
Speaker 2: the SRM looks at its token, looks at the resources
Speaker 2: security descriptor, and makes the call allow or deny access.
Speaker 1: Tokens and security descriptors yes, central players, yeah, okay. The
Speaker 1: material then dives into security descriptors and sids. What's the
Speaker 1: relationship there.
Speaker 2: Sid's security identifiers are the unique names for users, groups, computers,
Speaker 2: anything the system needs to identify for security.
Speaker 1: Think of them like unique ideas, and they're inside security
Speaker 1: descriptors right.
Speaker 2: Security descriptors use sids to specify who is being allowed
Speaker 2: or denied access. The source shows using get into SID
Speaker 2: to translate the raw SID string like S one five, three, two, five.
Speaker 1: Four five into built users.
Speaker 2: Exactly, translating the system's internal ID into something we recognize.
Speaker 1: So sids are the language of security identity. Next the
Speaker 1: object manager and its name space. This sounds like how
Speaker 1: the kernel keeps all its objects organized. It is.
Speaker 2: Think of the object manager name space the OMNS as
Speaker 2: like a hidden file system just for kernel.
Speaker 1: Objects, a file system for kernel stuff.
Speaker 2: Yeah, it's hierarchical like folders and files. Get ant type
Speaker 2: shows you the kinds of objects in there. Directory, symbolic link, token,
Speaker 2: process thread, lots more directory objects build the hierarchy and the.
Speaker 1: Source mentions the anti object PowerShell drive.
Speaker 2: Right that lets you browse this hidden name space using
Speaker 2: familiar commands like LS or CD. It's a fantastic way
Speaker 2: to explore.
Speaker 1: Very cool. And one specific directory gets called out Base
Speaker 1: named objects. Why is that one special?
Speaker 2: Ah? Base Named objects or B and O. That's the
Speaker 2: standard place where different processes potentially running as different users
Speaker 2: can create named kernel objects that they can then share.
Speaker 1: So for interprocess community sharing resources.
Speaker 2: Exactly, if you want two different programs to easily find
Speaker 2: and use the same kernel object like a mutex or
Speaker 2: an event, putting it in B and O is the
Speaker 2: common way to do it. It's the public square for
Speaker 2: named kernel objects.
Speaker 1: Okay, shared resources go there makes sense. Now back to
Speaker 1: system calls. The deep dive mentiones NT and ZW prefixes.
Speaker 1: Is there a big difference for us calling.
Speaker 2: From user mode? Not really the sources they're mostly interchangeable
Speaker 2: from our perspective, and crete mutant ZW crete mutant. They
Speaker 2: generally do the same thing when called from an application.
Speaker 1: Okay, so just note they signal a system call, right.
Speaker 2: And they usually follow that verb noun pattern too, like
Speaker 2: create followed by the object type mutant.
Speaker 1: Got it. The source also mentions unicodestring structures for parameters,
Speaker 1: especially names. What's important about those?
Speaker 2: So many system calls take names using this Unicodes string structure.
Speaker 2: It's not just a pointer to the characters. It also
Speaker 2: includes the strings current length, invites, and the buffer's maximum.
Speaker 1: Size self describing strings.
Speaker 2: Yeah, and crucial, the length is just the characters used,
Speaker 2: not including a null terminator. In fact, you can have
Speaker 2: null characters inside object names at this level.
Speaker 1: Really, that seems like it could cause problems.
Speaker 2: It can mishandling these counted strings versus null terminated strings
Speaker 2: has definitely been a source of security bugs over the years.
Speaker 2: It uses UCS two encoding.
Speaker 1: By the way, good detail. Okay, so a system call runs,
Speaker 1: it needs to report back success, failure, what happened. That's
Speaker 1: where anti status codes come in.
Speaker 2: Exactly, and status codes are the standard return values. They
Speaker 2: tell you the outcome, and.
Speaker 1: They're more than just error or okay, oh yeah.
Speaker 2: The source breaks down the structure. There's a severity level
Speaker 2: success info, warning, error, a facility code telling you which
Speaker 2: part of the system generated the status like default debugger
Speaker 2: win thirty two, and the specific status code number.
Speaker 1: So lots of context.
Speaker 2: Tons and get end status in the PowerShell module lets
Speaker 2: you look up these codes, get the symbolic name and
Speaker 2: the message text. Super useful for debugs.
Speaker 1: And PowerShell itself often turns these into exceptions.
Speaker 2: We see right when a PowerShell command wraps a system
Speaker 2: call and gets an error and sisteris it often surfaces
Speaker 2: that as a dot net exception. The example of get
Speaker 2: ent directory on a non existent.
Speaker 1: Path gives that object name not found exception.
Speaker 2: Yep, and you can take the error code from that exception,
Speaker 2: feed it to get end status and get the underlying
Speaker 2: into status info. It shows how PowerShell bridges that low
Speaker 2: level kernel world with the managed dot net.
Speaker 1: World neat connection. Okay, next topic, object handles. User applications
Speaker 1: don't touch kernel objects directly. They use these handles as
Speaker 1: like tickets.
Speaker 2: Precisely, when you successfully create or open a kernel object
Speaker 2: via a system call, the kernel gives your process back
Speaker 2: a handle. Think of it as an index number into
Speaker 2: your process's private handle table.
Speaker 1: And what's in that handle table entry Three key things.
Speaker 2: The handle number itself, the access rights that were granted
Speaker 2: to your process for that object like read, write, synchronize,
Speaker 2: and critically a pointer to the action object down in
Speaker 2: kernel memory.
Speaker 1: So when my app uses that handle later, say, to
Speaker 1: read from a file.
Speaker 2: Object, it passes the handle number in another system call.
Speaker 2: The kernel uses that number to look up the entry
Speaker 2: in your process as handle table. Then it does vital
Speaker 2: checks like what First, it checks if the access you're
Speaker 2: requesting now, say read access is allowed by the access
Speaker 2: rights granted when the handle was created stored in the table. Second,
Speaker 2: it checks if the handle actually points to the right
Speaker 2: type of object trying to read from a mutex handle
Speaker 2: that's going to fail.
Speaker 1: Makes sense, access check and type check. Secure way to
Speaker 1: manage things, which brings us to access masks those granted
Speaker 1: rights right.
Speaker 2: The permissions granted are stored as a thirty two bit
Speaker 2: number called an access mask. It's a bitfield. Different bits
Speaker 2: mean different permissions.
Speaker 1: And it's specific to the object type largely.
Speaker 2: Yes, the top sixteen bits are generally type specific. So
Speaker 2: a file object's access mask will have bits for things
Speaker 2: like read data, write data, a pen data, while a
Speaker 2: thread object will have bits for terminate, suspend, resume, set information,
Speaker 2: and so.
Speaker 1: On, granular permissions tailored to the object. The source then
Speaker 1: shows duplicating handles with copynt object. Why would you do that?
Speaker 2: Copy anti object lets you duplicate an existing handle. You
Speaker 2: can just make an identical copy or and this is useful.
Speaker 2: You can request different access rights for the new handle.
Speaker 1: Ah, so you could create a less privileged version of
Speaker 1: a handle exactly.
Speaker 2: Maybe you have a handle with full access, but you
Speaker 2: want to pass a handle to another part of your
Speaker 2: code or another process that only has a query access.
Speaker 2: Duplicating the handle with a restricted desired access mask is
Speaker 2: how you do that.
Speaker 1: Smart and compare and object checks if two handles point
Speaker 1: to the same actual kernel object.
Speaker 2: Yep, even if they have different access rights. Compare end
Speaker 2: to object tells you if they're ultimately referencing the same
Speaker 2: thing done in the kernel.
Speaker 1: Cool. What about that protect from close attribute sounds obvious?
Speaker 2: It is what it sounds like. If you set that
Speaker 2: astribute on a handle, the system won't let it be closed.
Speaker 2: Palls to close handle will fail with status handle not closeable.
Speaker 1: Why to keep a critical handle alive?
Speaker 2: Could be maybe you need to guarantee a resource stays
Speaker 2: accessible and don't want some stray code closing the handle prematurely.
Speaker 1: Okay. The deep dive then talks about enquery information object
Speaker 1: and end set information object, sort of generic get and
Speaker 1: set for object data.
Speaker 2: That's the idea. Instead of having dozens of specific system
Speaker 2: calls for every little piece of info about every object type,
Speaker 2: the kernel provides these general purpose calls.
Speaker 1: How do they work?
Speaker 2: You give them the handle, an information class number that
Speaker 2: specifies what data you want, and a buffer to put
Speaker 2: the data in for query or get from for set.
Speaker 1: And how do you know the right information class number? Ah?
Speaker 2: Well, get nt object information class can list the known
Speaker 2: ones for an object type, but as the source notes,
Speaker 2: not all classes are officially documented. Sometimes it involves a
Speaker 2: bit of digging or experimentation, like.
Speaker 1: Figuring out database fields. The example with querying process info
Speaker 1: and getting buffer too small that highlights needing the right
Speaker 1: buffer size exactly.
Speaker 2: You often have to figure out how much space the
Speaker 2: information needs. Sometimes you call it once to get their
Speaker 2: required size, allocate a buffer, then call it again, or
Speaker 2: just guess with the like parameter until it works.
Speaker 1: Got it okay? Quickly. Touching on device objects and symbolic
Speaker 1: links in the OMNS. How do they fit in?
Speaker 2: Device objects represent hardware or virtual devices. You can see
Speaker 2: them under nty object. Device Symbolic links like system root
Speaker 2: are just pointers or aliases to other paths in the OMNS.
Speaker 1: So when I open see windowsnoepad dot.
Speaker 2: Ex, the system uses symbolic links C likely points to
Speaker 2: a device hard disc volume X path. Windows might involve
Speaker 2: system route to resolve the path down to the actual
Speaker 2: file object, passing through the device object representing the disk volume,
Speaker 2: all involving the object manager.
Speaker 1: Path resolution involves the OMMS. Okay, next, process and thread
Speaker 1: manager key security points.
Speaker 2: Processes and threads are the things that run code, and
Speaker 2: they are securable objects themselves. They have security descriptors, so you.
Speaker 1: Need permission to say terminate another process.
Speaker 2: Absolutely and importantly you generally can't open a process or
Speaker 2: thread just by knowing its name. You need its unique
Speaker 2: process ID PID or thread id TID helps prevent arbitrary
Speaker 2: interference just based on names.
Speaker 1: Right, need the specific ID. Okay. Memory management in sections
Speaker 1: sounds like fertile ground for security issues.
Speaker 2: Definitely. Sections are blocks of memory that can be shared
Speaker 2: between processes. New antisection creates one add in section, maps
Speaker 2: it into a process's address space.
Speaker 1: And you control permissions on that memory.
Speaker 2: Yes crucial. You specify protection like read only read write,
Speaker 2: execute read write. The kernel enforces these. Trying to map
Speaker 2: a section with incompatible permissions fails, as the example.
Speaker 1: Showed and shared ritable sections. The source mentions CVE twenty
Speaker 1: nineteen Uro nine, four to three. That sounds bad.
Speaker 2: It was a privileged process shared a section. A lower
Speaker 2: privileged process could map it as writable modified data the
Speaker 2: privileged process trusted and potentially get code execution. Big problem.
Speaker 1: Yikes. How would you even find such shared sections?
Speaker 2: The source shows using get and handle to look at
Speaker 2: all handles and processes, filtering for section objects, and using
Speaker 2: test n access mask to see if any have right
Speaker 2: access section map right or potentially dangerous combinations like section
Speaker 2: exten size. You'd compare handles between a high privilege and
Speaker 2: low privileged process, so.
Speaker 1: You can hunt for potentially risky sharing configurations and even
Speaker 1: fuzz them.
Speaker 2: Yeah, if you find a writable shared section, you could
Speaker 2: use right anti virtual memory to poke at it, write
Speaker 2: unexpected data. See if you can crash or exploit the
Speaker 2: other process sharing it. Show in t section even gives
Speaker 2: you a x editor GUI for it.
Speaker 1: Wow. The big takeaway seems to be writable and executable
Speaker 1: memory is inherently dangerous.
Speaker 2: Extremely that combo is classic malware territory for code injection.
Speaker 2: He's very careful justification if you used at all?
Speaker 1: Okay, shifting up a level. Now user mode applications and
Speaker 1: Win thirty two APIs. This is where most developers live. Right,
Speaker 1: how does this relate to the kernel stuff?
Speaker 2: Right? Most apps don't call nt create file directly. They
Speaker 2: call the Win thirty two API function create file. These
Speaker 2: Win thirty two APIs are the documented stable interface for applications,
Speaker 2: the layer of abstraction exactly. They provide functions for everything files,
Speaker 2: Windows network registry under the hood. Many of these WIN
Speaker 2: thirty two functions eventually translate into one or more and
Speaker 2: or ZW system calls to the kernel to do the
Speaker 2: actual work. Understanding that translation is key, So.
Speaker 1: Win thirty two is the friendly face. System calls are
Speaker 1: the engine room. Okay. DLL imports and API sets what
Speaker 1: are these?
Speaker 2: Ds? Dynamic link libraries are shared code libraries. Apps import
Speaker 2: functions from them. Get Win thirty two module import. Let's
Speaker 2: you see which functions and app uses from which DLLs.
Speaker 1: Useful for understanding dependencies and API.
Speaker 2: Sets Introduced in Windows seven. They're like virtual DLLs, and
Speaker 2: app might link against apm's wind core process threads LANs
Speaker 2: onesaushal on zero dot dll instead of directly against kernel
Speaker 2: thirty two dot dll or at VAP thirty two dot dll.
Speaker 2: It decouples the app from the exact DLLLL Providing the
Speaker 2: function makes it easier for Microsoft to refactor things behind
Speaker 2: the scenes without breaking apps. Get n TAPA set. Let's
Speaker 2: you see which real DLL actually backs a specific API
Speaker 2: set on your system as flexibility.
Speaker 1: Okay, next, searching for DLLs and DL hijacking. This is
Speaker 1: a classic attack, right Oh yeah?
Speaker 2: Very common. When an app asks to load a DLL
Speaker 2: just by name like graphics dot DLL without a full path,
Speaker 2: Windows has to.
Speaker 1: Search for it where does it look.
Speaker 2: The search order has changed over time for security reasons.
Speaker 2: Older Windows versions often check the app's current directory first,
Speaker 2: which was dangerous.
Speaker 1: Because an attacker could drop a malicious graphics dot DLL.
Speaker 2: There precisely if a privileged app loaded it from an
Speaker 2: unsecured directory boom dll hijack code execution. Vista and later
Speaker 2: have a safer default order prioritizing system directories, but vulnerabilities
Speaker 2: can still exist if apps aren't careful about where they
Speaker 2: load DLLs from, or if their current directory is attacker can.
Speaker 1: Always specify the full path if you can't. Basically, Windows
Speaker 1: stations and desktops UI stuff, but security implications.
Speaker 2: Yes, Window stations are secure containers for UI elements, primarily desktops.
Speaker 2: WINDSTA is the main interactive one we use why separate
Speaker 2: stations Isolation services might run in a different Window station
Speaker 2: from the interactive user. It prevents processes in one station
Speaker 2: from easily interfering with the UI of another. Desktops live
Speaker 2: inside window stations, providing another layer. Get INNT window station
Speaker 2: name and get in desktop name.
Speaker 1: Let you list them boundaries even for the UI. Uh
Speaker 1: huh okay. Windows messages. How Windows talk to.
Speaker 2: Each other fundamentally, yeah, A message is just a number
Speaker 2: identifying the message type, plus a couple of parameters. Apps
Speaker 2: can send messages, wait for processing, or post them, put
Speaker 2: in a queue and continue.
Speaker 1: And windows belong to threads.
Speaker 2: Right. Each window has thread affinity. Only the thread that
Speaker 2: created it should really process its messages. That thread runs
Speaker 2: a message loop using APIs like get message and dispatch message.
Speaker 1: The source has a conceptual example of sending a message
Speaker 1: to notepad. Yeah.
Speaker 2: It shows finding the notepad window, get an itt window,
Speaker 2: maybe finding its edit child control, and conceptually how you'd
Speaker 2: send it a message, perhaps to pace text or close it.
Speaker 2: It shows the potential for programmatic UI interaction, which could
Speaker 2: be used for.
Speaker 1: Good or bad. Okay. Console sessions, we have the physical console,
Speaker 1: but also remote desktop, fast user switching exactly.
Speaker 2: Each of those creates a separate session get and T
Speaker 2: process info only group objects. Session edge shows you which
Speaker 2: session each processes in.
Speaker 1: Why separate sessions isolation?
Speaker 2: Again? Each session gets its own memory areas for certain things,
Speaker 2: its own instance of base named objects, its own window stations.
Speaker 2: Session zero is special reserve for system services usually no
Speaker 2: GUI there.
Speaker 1: Session zero for services that leads into shatter attacks and UIPI.
Speaker 1: What were shatter attacked?
Speaker 2: Back before Vista user apps and many services ran together
Speaker 2: in session zero, a low privileged app could send malicious
Speaker 2: window messages to a high privileged service window in the
Speaker 2: same session, tricking it into doing things or even running code.
Speaker 2: That was a shatter attack.
Speaker 1: Asked how is it fixed?
Speaker 2: Two main things Invista session zero isolation moved interactive users
Speaker 2: out of session zero and user interface privilege isolation UIPI
Speaker 2: was introduced.
Speaker 1: What does UIPI do.
Speaker 2: It prevents lower privileged low integrity level processes from sending
Speaker 2: most window messages to higher privileged process windows, even if
Speaker 2: they're on the same desktop in the same session. It
Speaker 2: blocks that message based attack vector.
Speaker 1: A crucial privilege boundary for the UI and the source
Speaker 1: mentioned procession based named objects in Windows directories again right.
Speaker 2: Under sessions ID base Named objects and sessions ID Windows.
Speaker 2: This keeps named objects and window stations isolated between different
Speaker 2: user sessions. NT object session drive lets you see the
Speaker 2: BNO for your current.
Speaker 1: Session isolation everywhere, okay. Comparing Win thirty two APIs versus
Speaker 1: system calls again using create mutexx Win thirty two and
Speaker 1: anti create mutant ciscle key differences.
Speaker 2: Look at the return values. Create mutech x returns the
Speaker 2: handled directly on success or NLL on failure. Anti create
Speaker 2: mutant returns an anti status code indicating success or failure,
Speaker 2: and the handle comes back through an output parameter a pointer.
Speaker 1: So Win thirty two often hides the anti status and
Speaker 1: pointer stuff.
Speaker 2: Yeah. It translates the anti status error into an NUL
Speaker 2: return or sets an error code retrievable via get laster.
Speaker 2: It's a more abstract, arguably simpler interface for the application developer.
Speaker 1: Got it registry interaction. The module has WIN thirty two.
Speaker 2: Path Yes, so you can use familiar paths like HKLM
Speaker 2: Software Microsoft with commands like get an it key instead
Speaker 2: of the native OMNS path Registry Machine.
Speaker 1: Software handy, and you can convert between them yep.
Speaker 2: The key objects return have properties like Win thirty two
Speaker 2: path and full path the OMNS path for easy conversion.
Speaker 1: PowerShell has built in registry drives HKLM HKCU. Why use
Speaker 1: the module's provider.
Speaker 2: Ah The NUL character issue malware sometimes hides keys or
Speaker 2: values by putting an NUL character inside the name the bill,
Speaker 2: and PowerShell provider can't handle those because it relies on
Speaker 2: annual terminated strings, but.
Speaker 1: The anti object module can yes.
Speaker 2: Because it uses the native APIs which work with counted strings,
Speaker 2: so it can see and interact with those hidden by
Speaker 2: annual entries, crucial for finding certain types of malware persistence.
Speaker 1: Meki okay path limits max path still a thing.
Speaker 2: Still a thing in many Win thirty two APIs that
Speaker 2: two hundred and sixty character limit two hundred and fifty
Speaker 2: nine usable for paths. Get anti file path demonstrates it.
Speaker 2: Try to convert a longer path and you'll get status
Speaker 2: name a too long.
Speaker 1: A classic Windows limitation process. Creation Yeah, anti create user
Speaker 1: process versus create process. We use create process usually.
Speaker 2: Always use create process or wrappers like start process or
Speaker 2: a new Win thirty two process. Anti create user process
Speaker 2: is the raw kernel call, but create process does a
Speaker 2: ton of essential setup work and user mode talking to CSRSS,
Speaker 2: setting up environment variables, et cetera.
Speaker 1: Skipping create process would lead to a broken process pretty much.
Speaker 2: It wouldn't be properly initialized for the user environment. New
Speaker 2: and thirty fo process is a wrapped around Create.
Speaker 1: Process and the source mentions command line parsing issues with
Speaker 1: new wind thirty two process.
Speaker 2: Right it tries to be helpful splitting on spaces adding
Speaker 2: lot exx. But if you just give it, say C
Speaker 2: program files my app and there's also a C program
Speaker 2: dot exx which one.
Speaker 1: Runs, ambiguity and potential hijacking.
Speaker 2: Exactly if a privileged process runs something based on a
Speaker 2: path that could be manipulated, like relying on the path, environment,
Speaker 2: variable or relative paths, it could be tricked into running
Speaker 2: the wrong executable or loading malicious DLLs. Best practice use
Speaker 2: applicate application name with the full explicit path to the
Speaker 2: executable you intend to run.
Speaker 1: Be specific, avoid ambiguity. Okay, Shell APIs and file associations.
Speaker 1: How does double clicking my doc dot txt work?
Speaker 2: Explorer doesn't try to run my doc dot txt. It
Speaker 2: looks up the file association for dot txt in the registry,
Speaker 2: finds that notepad or whatever is the handler. Then it
Speaker 2: uses shell APIs probably shall execute, telling it to open
Speaker 2: my dooc dot txt using notepad.
Speaker 1: So new wind thirty two pm dot txt.
Speaker 2: Would fail yep, because not txt isn't an executable. You
Speaker 2: need that shell layer to handle document types. The source
Speaker 2: shows querying the registry to find the handler and mentions
Speaker 2: shell execute verbs like open print et cetera.
Speaker 1: Smart indirection Okay, quick recap, LSAs and SCM.
Speaker 2: Still vital, absolutely fundamental. LSS Local Security Authorities subsystem handles authentication,
Speaker 2: log on sessions, security policy, SCM Service Control Manager manages
Speaker 2: background services, core security infrastructure.
Speaker 1: Got it now? Finding those hidden registry keys with NUL
Speaker 1: characters again, how.
Speaker 2: Exactly the source shows creating one with new end key
Speaker 2: embedding a zero back take zero in the name string.
Speaker 2: Then you use else recurs in the NT object registry
Speaker 2: derive and pipe it to where object name matches zero
Speaker 2: to find keys containing that NUL.
Speaker 1: And for hidden values.
Speaker 2: Similar idea, Create a value with an NUL in its name,
Speaker 2: then use a custom function like the select hidden value shown,
Speaker 2: which likely iterates through value names character by character looking
Speaker 2: for the nul. It bypasses the standard tools limitation.
Speaker 1: Very clever, okay, Final section intro. Tokens. We mentioned them,
Speaker 1: but let's define them clearly right.
Speaker 2: Tokens are the objects that represent the security context of
Speaker 2: a process or thread. Who is it? What can it do?
Speaker 2: Two main types primary tokens Every process has one, defines
Speaker 2: its main identity, usually the user who launched it. And
Speaker 2: impersonation tokens allow a thread to temporarily act with a
Speaker 2: different identity, maybe a client's identity for a specific task.
Speaker 1: Primary is the baseline. Impersonation is temporary borrowing. Sets us
Speaker 1: up nicely for the next part.
Speaker 2: YEP, Now we dive into what's in those tokens and
Speaker 2: how they're used.
Speaker 1: All right, let's unpack primary tokens in more detail. These
Speaker 1: are the main ID badges for processes.
Speaker 2: Right, that's exactly it. Every running process gets one. It
Speaker 2: holds the security identity, primarily the SID of the user
Speaker 2: account that started.
Speaker 1: It, and this is what the SRM looks at for
Speaker 1: access checks.
Speaker 2: Correct. When that process tries to touch a file or
Speaker 2: registry key, whatever, the SRM grabs this primary token and
Speaker 2: compares it against the resources security descriptor.
Speaker 1: And the source mention. Figure four two showing the token details.
Speaker 2: What are the critical parts, Yeah, that figures helpful. Key
Speaker 2: things are the user SID obviously, the token type primary
Speaker 2: versus impersonation, maybe an impersonation level if it's that type.
Speaker 2: And then those four sixty four bit IDs.
Speaker 1: Right, token ID, authentication.
Speaker 2: ID, authentication ID, origin login ID, and modified ID. The
Speaker 2: token ID is just a unique identifier for this specific
Speaker 2: token instance.
Speaker 1: But the authentication ID seems important, linking back to a
Speaker 1: log on session very important.
Speaker 2: When you log on, Elsas creates a log on session
Speaker 2: and the SRM assigns it a unique authentication ID. Every
Speaker 2: token created during that session gets the same authentication ID,
Speaker 2: So if I.
Speaker 1: Log off and log back on, I get a new authentication.
Speaker 2: IDY, even if you're the same user. It distinguishes different
Speaker 2: login instances. Helps with auditing and resource management.
Speaker 1: Makes sense, and we can see this with get in
Speaker 1: token right.
Speaker 2: Get in token grabs the token object. You can then
Speaker 2: look properties like token dot user or use format in
Speaker 2: token for a nicely formatted summary.
Speaker 1: What does format and token show?
Speaker 2: User groups with their sids and attributes, privileges and key
Speaker 2: stuff all shows even more and show in token gives
Speaker 2: you that GUI view similar to the figure commandline.
Speaker 1: And GUI good options. Okay, impersonation tokens? Why does services
Speaker 1: use these? So?
Speaker 2: A service often running as a powerful account like system
Speaker 2: might need to access a resource on behalf of a
Speaker 2: specific user who connected to it, like reading that user's files.
Speaker 1: But the system account might not have permission for that
Speaker 1: user's files.
Speaker 2: Directly exactly, so the service thread temporarily impersonates the user
Speaker 2: who made the request. It borrows their identity using an
Speaker 2: impersonation token. Now when it accesses the file, the SRM
Speaker 2: check uses the user's identity from the impersonation token, not
Speaker 2: the service's identity, a way.
Speaker 1: To act as the user for a specific task. The
Speaker 1: source showed trying different impersonation levels with invoke in token
Speaker 1: and getting an.
Speaker 2: Error right this status bat impersonation level error. It tried
Speaker 2: impersonating at the identification level, which is very weak lets
Speaker 2: the server see who the client is, but not act
Speaker 2: as them, especially not remotely.
Speaker 1: So trying to open an object failed.
Speaker 2: Yes, because that operation required a higher level, probably impersonation level,
Speaker 2: which does allow acting locally as the client. It wasn't
Speaker 2: an access denied on the object itself, but a failure
Speaker 2: because the type of impersonation wasn't sufficient for the action.
Speaker 1: Subtle but important difference and duplicating a token handle isn't
Speaker 1: the same as duplicating the token object correct.
Speaker 2: Duplicating the handle just gives you another reference pointer to
Speaker 2: the same token To create a new independent token object
Speaker 2: based on another, like making an impersonation token from a
Speaker 2: primary one, you need the duplicate access right on the
Speaker 2: original token.
Speaker 1: Handle and you use anti duplicate token.
Speaker 2: Which is wrapped by copy and token and PowerShell. That
Speaker 2: creates a whole new token object you can then modify
Speaker 2: or use for impersonation. The source shows creating a delegation
Speaker 2: level token. This way, that's the highest level, allowing remote
Speaker 2: impersonation to delegation.
Speaker 1: Sounds powerful and potentially risky. Well, okay. The use for
Speaker 1: deny only attribute on sids in a token. How does
Speaker 1: that work?
Speaker 2: It changes how the SRM evaluates acees. If a SID
Speaker 2: in your token has used for denyingly set that SID
Speaker 2: only counts when checking deny acees in a security descriptor.
Speaker 2: It's completely ignored for allow aces.
Speaker 1: So it can only be used to deny access, not
Speaker 1: grant it.
Speaker 2: Pretty much, the example was good. You're in the employee
Speaker 2: group allow access and remote access group deny access marked
Speaker 2: use for nine only. The deny still wins because of
Speaker 2: that attribute. It lets you build rules where specific memberships
Speaker 2: explicitly block access even if other memberships would normally allow it.
Speaker 1: Explicit denials take precedence. Got it now. Token privileges These
Speaker 1: aren't access rights on objects, but system wide powers exactly.
Speaker 2: Privileges grant the ability to perform specific system operations regardless
Speaker 2: of object permissions. Get and token privilege lists them for
Speaker 2: a token. Examples see shut down privilege, reboot the machine.
Speaker 2: See change notified privilege bypassed drivers. Checking lets you access
Speaker 2: see users other user desktop even if you can't list
Speaker 2: other users. See load driver privileged load kernel drivers very
Speaker 2: powerful type to code signing. See take ownership privilege, become
Speaker 2: owner of file subjects, serie label privilege, change integrity labels.
Speaker 1: Big powers, need careful assignment, okay, sandbox tokens restricted right, restricted,
Speaker 1: low box. What's the goal here?
Speaker 2: Containment? Limit the damage If a process gets compromised, especially
Speaker 2: one handling untrusted input like a web browser or PDF reader,
Speaker 2: Run it with a weaker token, so even if hacked,
Speaker 2: it can't do much harm.
Speaker 1: Makes sense? How to restrict a tokens work? They're the
Speaker 1: oldest type.
Speaker 2: Yeah, you create a new token based on an existing one,
Speaker 2: but you add limitations. You specify restricting sids. These only
Speaker 2: count for allow acees, limiting what it can access. You
Speaker 2: can mark existing groups as use for deny only, and
Speaker 2: you can explicitly disable privilege, so.
Speaker 1: You surgically weaken the original token. Right.
Speaker 2: The example shows making one adding nt authority restricted, making
Speaker 2: everyone deny only disabling privileges. Browsers like Chrome Firefox use
Speaker 2: this concept heavily.
Speaker 1: Okay, what about right restricted tokens?
Speaker 2: Simpler, much simpler concept. A process with this token is
Speaker 2: blocked from writing to most things, but can usually still
Speaker 2: read and execute introduced in XPSP two for hardening services.
Speaker 1: Easier but maybe less secure.
Speaker 2: Potentially the source nodes a compromise. Process could still read
Speaker 2: sensitive files even if it can't write them.
Speaker 1: It's a trade off read okay, right blocked, got it
Speaker 1: and low box tokens.
Speaker 2: The source doesn't detail them much here, but they're a
Speaker 2: newer type often used with app containers. For UWP apps
Speaker 2: even more restrictive focus on deep isolation following least privilege principles.
Speaker 1: So different levels of sandboxing available via tokens. Shifting topics,
Speaker 1: administrator privileges if not just one root SID in Windows.
Speaker 2: Definitely not being an administray is more nuanced. It's a
Speaker 2: combination of things, usually membership in the builty in administrators
Speaker 2: group sid s one five thirty two five four four
Speaker 2: that group having powerful permissions granted on resources, and the
Speaker 2: token possessing certain key privileges. Which privileges are typically admin
Speaker 2: level things like c create token privilege, make new tokens,
Speaker 2: CTB privilege act as part of the OS extremely powerful
Speaker 2: cetic ownership privilege, ce load driver privilege see a HEP privilege,
Speaker 2: SARAH store privilege see the bug privilege, access any processes
Speaker 2: memory see impersonate privilege. Having these indicates administrative capability and.
Speaker 1: The source mentioned elevated sids based.
Speaker 2: On the RA yeah kind of kernel shortcut for certain checks.
Speaker 2: Instead of looking for specific well known sids, the kernel
Speaker 2: just checks the last number the RID. If it's say
Speaker 2: five hundred and forty four administrators RID or five forty
Speaker 2: five users RID, it treats it as having that role
Speaker 2: in certain contexts.
Speaker 1: Interesting pattern matching, okay. User count control UAC and elevation
Speaker 1: the pop up boxes.
Speaker 2: We are right. UAC aims to have even administrators run
Speaker 2: with standard user rights by default. When you need to
Speaker 2: do something requiring admin rights, UAC prompts for consent. If
Speaker 2: you give it, the task runs elevated with your full
Speaker 2: administrator token.
Speaker 1: And apps can request elevation automatically.
Speaker 2: True their manifest file Yeah, an XML file embedded in
Speaker 2: the dot ex get executable manifest shows it. It specifies
Speaker 2: an execution level as invoker, run as caller, highest available,
Speaker 2: run elevated if possible or required.
Speaker 3: Administrator must elevate and how do you manually elevate something?
Speaker 2: Start processed after verb runas in PowerShell or using the
Speaker 2: shell execute API with the runa's verb both trigger the
Speaker 2: UAC prompt if needed.
Speaker 1: Okay, link tokens and elevation type. What's that?
Speaker 2: When an admin logs in UAC actually creates two tokens,
Speaker 2: a standard limited one and the full admin one, they're linked.
Speaker 2: Elevation is the process of switching from the limited token
Speaker 2: to the full one for a specific task.
Speaker 1: After UAC consent, split tokens one limited one full makes sense?
Speaker 1: Security attributes more data in tokens.
Speaker 2: Yeah, Extra bits of info beyond sids and privileges can
Speaker 2: be strings, numbers, sids, binary data. They add more context
Speaker 2: for potentially finer grained access decisions, especially with conditional acees
Speaker 2: can have flags like non inheritable, case sensitive new end
Speaker 2: token can add them, but needs see create token privilege.
Speaker 1: More context for decisions. Okay. Token assignment and impersonation criteria.
Speaker 1: What rules apply when assigning or impersonating tokens.
Speaker 2: Assigning a primary token if not inherited, needs assigned primary
Speaker 2: access on the token. Kernel checks integrity levels, log on
Speaker 2: session relationships. Impersonation is more complex see token can impersonate
Speaker 2: function check's integrity levels, can't impersonate higher privileges See impersonate
Speaker 2: Privilege often needed UPI flags, log on sessions, user sids.
Speaker 1: And the system account gets special treatment big.
Speaker 2: Time because user log on sessions ultimately derive from the
Speaker 2: initial system session. System can basically impersonate any user token
Speaker 2: of equal or lower integrity, even without seeing person at privilege.
Speaker 2: It's implicitly trusted in that way.
Speaker 1: Wow. System is powerful and Windows ten added a check
Speaker 1: for the elevated flag.
Speaker 2: Right before wind ten. You could potentially impersonate and admin's
Speaker 2: elevated token if you first lowered its integrity level. Win
Speaker 2: ten added a check you can't impersonate the elevated token
Speaker 2: of the same user if your current token isn't also elevated,
Speaker 2: closed a potential loophole.
Speaker 1: Good hardening step and test antoken impersonation checks if impersonation.
Speaker 2: Is allowed YEP, and set antoken integrity level lets you
Speaker 2: change integrity levels. Useful for testing these rules.
Speaker 1: Okay? Finding UI access processes? What are they and why
Speaker 1: look for them?
Speaker 2: Processes with the UI Access's flag set in their token
Speaker 2: can bypass some UIPI restrictions. They can send messages to
Speaker 2: higher privileged windows, needed for things like screen readers, accessibility.
Speaker 1: Tools, but potentially risky if nowhere gets.
Speaker 2: It exactly, so finding them is useful. The source shows
Speaker 2: get and process with excess query limited information and a
Speaker 2: filterscript checkingtoken dot UI access to list them identifies processes
Speaker 2: with that special UI interaction capability.
Speaker 1: Good to note okay. Final major topic security descriptors the
Speaker 1: actual rules. What are the components?
Speaker 2: Four main parts Owner SID, who controls the permissions Group
Speaker 2: SID mostly for POSTX compatibility less used in Windows, access checks,
Speaker 2: DACL Discretionary Access Control List, and SACL System Access Control List.
Speaker 1: DCL is where the allowed NY rules live exactly.
Speaker 2: It's a list of AC's access control entries. Each AC
Speaker 2: says six gets allowed to I access Y. The acess
Speaker 2: mask Y details the specific permissions and the SECL primarily
Speaker 2: for auditing ACS. There say a log an event if
Speaker 2: SidD X tries axs Y and succeeds fails. Since Vista,
Speaker 2: it also holds mandatory integrity lobles, non auditing, ACEES.
Speaker 3: Owner group, DACL, SACL, got it well known sad's predefined
Speaker 3: identifiers YEP, consistent across systems, NL, SID, everyone, WD, local
Speaker 3: creator owner, built in.
Speaker 2: Users BU system sy administrators B authenticated users AU medium
Speaker 2: mandatory level lots of them. They have a structure revision
Speaker 2: authority like NT authority five. Then relative identifiers built in
Speaker 2: users is S one five thirty two five forty five
Speaker 2: authority five RIDE thirty two for builton domain ride five
Speaker 2: forty five for users group.
Speaker 1: Hierarchical structure access control lists ACLS. The DACL and SACL
Speaker 1: are types of these.
Speaker 2: Structure simple header revision size followed by the list of ACS.
Speaker 2: Revision tells you the ACL version two, three four commonly, and.
Speaker 1: The access control entries acees themselves.
Speaker 2: ACE header type, flag size, and type specific data. For
Speaker 2: standard loagenie acees, the data is the SID and the
Speaker 2: access mask. Many types allow deny audit callback object ACS
Speaker 2: for property specific permissions.
Speaker 1: And AC flags modified behavior.
Speaker 2: Right inherently inherited from parent. Critical successful access, failed access
Speaker 2: for auditing, fine grained control okay.
Speaker 1: Constructing and viewing security descriptors with PowerShell.
Speaker 2: New n Security Descriptor lets you build one setting owner group,
Speaker 2: adding ACS format and security discret Victor is key for
Speaker 2: viewing shows owner group, DAC l ACS sec LACS clearly
Speaker 2: use show all and map generic for more detail and
Speaker 2: friendly permission names also shows control flex for the sd itself.
Speaker 1: Powerful Inspection Tools Security Descriptor Definition Language SDDL.
Speaker 2: The text format yeah much easier to read, write and
Speaker 2: store than binary blobs. Get NTCID. SDDL converts a SID
Speaker 2: to its SDDL string. Has aliases like wd BA, s y,
Speaker 2: A U, i U for well known sids, human.
Speaker 1: Readable security descriptors and conditional expressions in SDDL for dynamic rules.
Speaker 2: Exactly ACS that only apply if conditions based on security
Speaker 2: attributes in the token or on the resource are met
Speaker 2: at access time. Use attributes like token, integrity level, TI, user, SID, TU,
Speaker 2: device properties, et cetera. Uses operators like containers and errata
Speaker 2: adds huge flexibility.
Speaker 1: Context where access control cool Finally brute forcing known sids
Speaker 1: with get account sids.
Speaker 2: How why the function takes a base SID like S
Speaker 2: one five for NT authority and a range of IDs
Speaker 2: it tries. Each ried constructs the full SID and attempts
Speaker 2: to look up the account name. If it finds a
Speaker 2: name from the local system LSS, it means that SID exists.
Speaker 1: So you can discover accounts by iterating rids YEP.
Speaker 2: Useful for mapping out all the built in accounts and
Speaker 2: groups under S one five or S one five thirty
Speaker 2: two built in as the example shows a discovery technique.
Speaker 1: A systematic way to find existing principles. Wow, that brings
Speaker 1: us to the end of this really really deep dive.
Speaker 2: It certainly covered a lot of ground, from setting up PowerShell,
Speaker 2: the language basics all the way down into kernel objects, handles, tokens,
Speaker 2: security descriptors. It's intricate stuff, it really is.
Speaker 1: But it's amazing how PowerShell, especially with modules like the
Speaker 1: one discussed in the source, lets you interact with and
Speaker 1: really understand these core window security mechanisms.
Speaker 2: Absolutely it pulls back the curtain and having gone through
Speaker 2: this gives you a fantastic foundation. You know, you can
Speaker 2: now dig deeper into specific areas process security, privileged management, ecls,
Speaker 2: on specific objects, whatever interests you or is relevant to
Speaker 2: your work.
Speaker 1: Definitely, powershow really is the key to unlocking a lot
Speaker 1: of this.
Speaker 2: It provides the tools to explore as far as you
Speaker 2: want to go.
Speaker 1: So the final thought to leave you with knowing just
Speaker 1: how granularly Windows controls access down to individual permissions and attributes.
Speaker 1: What are some maybe unexpected ways this might impact application
Speaker 1: behavior or security configurations you see every day. Certainly gives
Speaker 1: you a new perspective. Thanks for joining us on this
Speaker 1: deep dive