{"id":87,"date":"2020-11-01T18:47:48","date_gmt":"2020-11-01T17:47:48","guid":{"rendered":"http:\/\/theredwindows.net\/?p=87"},"modified":"2021-07-30T18:27:50","modified_gmt":"2021-07-30T16:27:50","slug":"powershell-exemple","status":"publish","type":"post","link":"https:\/\/theredwindows.net\/index.php\/2020\/11\/01\/powershell-exemple\/","title":{"rendered":"PowerShell &#8211; Exemple"},"content":{"rendered":"\n<p>Dans cet article nous verrons comment programmer une fonction avanc\u00e9 permettant de lister les comptes locaux d\u2019une machine appartenant au m\u00eame domaine que la n\u00f4tre, dans le style &#8220;PowerSploit&#8221;, c\u2019est \u00e0 dire que les informations sont affich\u00e9 uniquement si le param\u00e8tre <code>-Verbose<\/code> est sp\u00e9cifi\u00e9 et retourne un objet (au lieu de l\u2019afficher). Je vous invite \u00e0 essayer de cr\u00e9er la fonction en m\u00eame temps sans voir la solution. La fonction sera test\u00e9e sur un domaine m&#8217;appartenant, le m\u00eame que celui utilis\u00e9 dans l&#8217;article traitant de l&#8217;utilisation offensive de GPO en environnement active directory.<\/p>\n\n\n\n<h3>D\u00e9finition<\/h3>\n\n\n\n<p>Ce sera une fonction avanc\u00e9e, elle doit poss\u00e9der diff\u00e9rents arguments, ils sont: <code>Identities<\/code> (permet de sp\u00e9cifier un\/des utilisateur(s) pr\u00e9cis \u00e0 \u00e9num\u00e9rer) il s&#8217;agit d\u2019une liste de <code>String<\/code> ses alias seront <code>Identity<\/code> ainsi que <code>User<\/code> et <code>Users<\/code>. <code>Properties<\/code> (permet de sp\u00e9cifier une propri\u00e9t\u00e9, ou plusieurs, \u00e0 afficher). L\u00e0 aussi il s&#8217;agit d\u2019une liste de &#8220;String&#8221; et aura comme alias <code>Property<\/code>. <code>ComputerName<\/code> (sp\u00e9cifie la machine cible, par d\u00e9faut la n\u00f4tre) qui est une cha\u00eene de caract\u00e8re, qui n\u2019est accept\u00e9e que si elle n\u2019est ni vide ni nulle. Enfin <code>Credential<\/code> (qui permet d\u2019utiliser des identifiants alternatifs pour se connecter). La fonction retourne <code>System.Object[]<\/code> et <code>System.Management.Automation.PSCustomObject<\/code>. La fonction ressemblera donc \u00e0 cela:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">function Get-NetLocalUsers {\n    [OutputType([System.Object[]], [System.Management.Automation.PSCustomObject])]\n    [CmdletBinding()]\n\n    param (\n\n        [Parameter(Mandatory=$false, Position=0, ValueFromPipeline=$true)]\n        [Alias(\"Identity\", \"User\", \"Users\")]\n        [String[]]\n        $Identities,\n\n        [Parameter(Mandatory=$false, Position=1, ValueFromPipeline=$true)]\n        [Alias(\"Property\")]\n        [String[]]\n        $Properties,\n\n        [Parameter(Mandatory=$false, Position=2, ValueFromPipeline=$true)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ComputerName = $env:COMPUTERNAME,\n\n        [Parameter(Mandatory=$false, Position=3, ValueFromPipeline=$false)]\n        [System.Management.Automation.CredentialAttribute()]\n        [System.Management.Automation.PSCredential]\n        $Credential = [System.Management.Automation.PSCredential]::Empty\n    )\n}<\/pre>\n\n\n\n<h3>Instructions<\/h3>\n\n\n\n<p>La fonction n\u2019a pas besoin d\u2019un <code>BEGIN<\/code>; dans le <code>PROCESS<\/code> il y aura donc toutes les instructions. Dans le <code>END<\/code> se situera tout ce qui concerne les valeurs de retours de la fonction. Pour faire les requ\u00eates il sera utilis\u00e9 <code>System.DirectoryServices.DirectoryEntry<\/code> les arguments qu\u2019acceptent l\u2019objet son en 1 le chemin, en 2 un nom d\u2019utilisateur et en 3 le mot de passe (ici il faut savoir si l\u2019argument est pass\u00e9 et en fonction adopt\u00e9e un comportement adapt\u00e9). Le chemin est constitu\u00e9 d\u2019une cha\u00eene de caract\u00e8re comme celle-ci <code>WinNT:\/\/COMPUTER<\/code>. Le r\u00e9sultat de l\u2019op\u00e9ration est sauv\u00e9 dans une variable. Les objets du chemin sont accessibles avec la m\u00e9thode <code>.Children<\/code> et les utilisateurs ont leur propri\u00e9t\u00e9 <code>SchemaClassName<\/code> \u00e9gal \u00e0 <code>user<\/code>. Il existe nombre de propri\u00e9t\u00e9s, en voici quelques-unes <code>Description<\/code>, <code>Name<\/code>, <code>objectSid<\/code>, <code>LogonScript<\/code>. Le tout est stock\u00e9 dans un tableau qui sera \u00e0 la fin retourn\u00e9 (l\u2019id\u00e9e ici est d&#8217;appliquer un filtre sur le champ <code>Name<\/code> si il est \u00e9gal \u00e0 l\u2019utilisateur dans le cas o\u00f9 il est sp\u00e9cifi\u00e9, ajouter le <code>PSObject<\/code> \u00e0 la liste). Voil\u00e0 \u00e0 quoi ressemble <code>PROCESS<\/code> et <code>END<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">    PROCESS {\n\n        try {\n\n            if ($PSBoundParameters[\"Credential\"]) {\n\n                Write-Verbose \"[Get-NetLocalUsers] Using alternate PSCredential\"\n                $ADSIObject = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList \"WinNT:\/\/$ComputerName\", $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password\n            } else {\n\n                $ADSIObject = New-Object System.DirectoryServices.DirectoryEntry -ArgumentList \"WinNT:\/\/$ComputerName\"\n            }\n        } catch {\n\n            Write-Verbose \"[Get-NetLocalUsers] Error while requesting $_\"\n            return\n        }\n\n        $ADSIUsers = ($ADSIObject.Children | Where-Object {$_.SchemaClassName -eq 'user'})\n        $Users = @()\n        \n        foreach ($user in $ADSIUsers) {\n\n            $psObject = New-Object System.Management.Automation.PSObject -Property @{\n\n                \"UserFlags\" = $user.UserFlags -as [System.String];\n                \"MaxStorage\" = $user.MaxStorage -as [System.String];\n                ...\n            }\n\n            if ($PSBoundParameters[\"Identities\"]) {\n\n                foreach ($Identity in $Identities) {\n\n                    if ($psObject.Name -like $Identity) {\n\n                        $Users += $psObject\n                    }\n                }\n            } else {\n\n                $Users += $psObject\n            }\n        }\n    }\n\n    END {\n\n        if ($PSBoundParameters[\"Properties\"]) {\n\n            return ($Users | Select-Object -Property $Properties | Format-List)\n        } else {\n\n            return $Users\n        }\n    }<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"953\" height=\"624\" src=\"http:\/\/theredwindows.net\/wp-content\/uploads\/2020\/10\/GetNetLocalUsers-1.png\" alt=\"\" class=\"wp-image-91\" srcset=\"https:\/\/theredwindows.net\/wp-content\/uploads\/2020\/10\/GetNetLocalUsers-1.png 953w, https:\/\/theredwindows.net\/wp-content\/uploads\/2020\/10\/GetNetLocalUsers-1-300x196.png 300w, https:\/\/theredwindows.net\/wp-content\/uploads\/2020\/10\/GetNetLocalUsers-1-768x503.png 768w, https:\/\/theredwindows.net\/wp-content\/uploads\/2020\/10\/GetNetLocalUsers-1-400x262.png 400w, https:\/\/theredwindows.net\/wp-content\/uploads\/2020\/10\/GetNetLocalUsers-1-800x524.png 800w\" sizes=\"(max-width: 953px) 100vw, 953px\" \/><figcaption>On dirait bien que notre fonction marche !<\/figcaption><\/figure>\n\n\n\n<p>Le script entier est disponible sur <a href=\"https:\/\/github.com\/rootSySdk\/PowerShellSample\/blob\/main\/Enum\/Get-NetLocalUsers.ps1\" data-type=\"URL\" data-id=\"https:\/\/github.com\/rootSySdk\/PowerShellSample\/blob\/main\/Enum\/Get-NetLocalUsers.ps1\">g<\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/rootSySdk\/PowerShellSample\/blob\/main\/Enum\/Get-NetLocalUsers.ps1\" data-type=\"URL\" data-id=\"https:\/\/github.com\/rootSySdk\/PowerShellSample\/blob\/main\/Enum\/Get-NetLocalUsers.ps1\" target=\"_blank\">ithub \u00e0 cette adresse<\/a> ! J\u2019esp\u00e8re que cette conclusion vous aura plu, amusez-vous bien !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans cet article nous verrons comment programmer une fonction avanc\u00e9 permettant de lister les comptes locaux d\u2019une machine appartenant au m\u00eame domaine que la n\u00f4tre, dans le style &#8220;PowerSploit&#8221;, c\u2019est \u00e0 dire que les informations sont affich\u00e9 uniquement si le param\u00e8tre -Verbose est sp\u00e9cifi\u00e9 et retourne un objet (au lieu de l\u2019afficher). Je vous invite [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts\/87"}],"collection":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/comments?post=87"}],"version-history":[{"count":5,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts\/87\/revisions"}],"predecessor-version":[{"id":251,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts\/87\/revisions\/251"}],"wp:attachment":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/media?parent=87"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/categories?post=87"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/tags?post=87"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}