PowerQuest.psm1

<#
    .SYNOPSIS
    Jeu d'administration système visant à développer l'aisance dans l'environnement de ligne de commande et à
    offrir une première expérience des nombreuses possibilités de PowerShell.
 
    .DESCRIPTION
    Chaque niveau contient une instruction et la solution qui est le mot de passe pour le niveau suivant.
    Tous les noms d'utilisateur contiennent le nom du jeu et le numéro de niveau (ex: "PowerQuest1").
    Une fois que vous pensez avoir terminé un défi, démarrez une nouvelle connexion au serveur et
    connectez-vous avec l'utilisateur suivant et le mot de passe que vous avez obtenu lors du défi précédent.
    En cas de succès, fermez la connexion précédente et commencez à résoudre le défi suivant.
    Ce concept est répété encore et encore jusqu'à ce que vous atteigniez la fin du jeu.
 
    Vous utiliserez SSH PowerQuest1@192.168.1.xxx ou
                    Enter-PSSession -ComputerName 192.168.1.xxx -Credential ~\PowerQuest1 pour vous connecter au jeu.
     
    Ne paniquez pas et n'abandonnez surtout pas car le but de ce jeu est d'apprendre !
     
    Les mots de passe sont sensibles à la case et sont à copier-coller ou à saisir tels qu'ils apparaissent à l'écran.
     
    Conseils qui peuvent vous aider dans le jeu, utilisez:
        – Internet
        – Get-Help
        – Get-Command
        – Get-Member
        – La touche « Tab » pour terminer vos commandes
        – Des notes pour stocker les mots de passe en local !
 
    .INPUTS
    Environnement système de la machine cible
 
    .OUTPUTS
    Comptes, fichiers et dossiers personnels des utilisateurs des différents niveaux
 
    .NOTES
    CC BY-NC-SA Franck Soubières - librement inspiré de "Under the Wire - PowerShell Training for the People"
 
    .LINK
    https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/plan/appendix-l--events-to-monitor
#>

function New-Level {
    param([String]$instruction,[String]$solution)
    $password = ConvertTo-SecureString $solution -AsPlainText -Force
    $Script:level++
    New-LocalUser "PowerQuest$Script:level" -Password $password -PasswordNeverExpires -UserMayNotChangePassword | Add-LocalGroupMember Administrateurs
    Start-Process "cmd.exe" -Credential (New-Object management.automation.pscredential "PowerQuest$Script:level",$password) -ArgumentList "/C"
    $SecureSolution = ConvertFrom-SecureString (ConvertTo-SecureString "Le mot de passe pour PowerQuest$Script:level est '$solution'." -AsPlainText -Force) -key(1..16)
    (New-Item "C:\Users\PowerQuest$($Script:level-1)\Instruction" -Value "Le mot de passe pour PowerQuest$Script:level est $instruction." -Force).Attributes = 'Hidden'
    (New-Item "C:\Users\PowerQuest$($Script:level-1)\Solution"    -Value $SecureSolution -Force).Attributes = 'Hidden'
}
function Get-Instruction {
    Get-Content "$env:USERPROFILE\Instruction"
}
function Get-Solution {
    $SecureSolution = ConvertTo-SecureString (Get-Content "$env:USERPROFILE\Solution") -key(1..16)
    (New-Object System.Management.Automation.PSCredential 'N/A', $SecureSolution).GetNetworkCredential().Password
    [int](Get-Content C:\Users\Malus)+1 | Set-Content C:\Users\Malus
}
function Disable-PasswordComplexity {
    secedit /export /cfg secpol.cfg
    (Get-Content secpol.cfg).Replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File secpol.cfg
    secedit /configure /db c:\windows\security\local.sdb /cfg secpol.cfg /areas SECURITYPOLICY
    Remove-Item -Force secpol.cfg -Confirm:$false
}
function Build-Levels {
    New-Level PowerQuest1 PowerQuest1
    # Niveau 1
    $mot_compose = 'hard_','unders_','s_','_en','en_','multi_','_team' | Get-Random
    New-Item "C:\Users\PowerQuest$Script:level\Documents\$mot_compose" -Force
    New-Level "le nom du fichier avec un '_' a remplacer par l'edition de PowerShell (variable)" $mot_compose.Replace('_',$PSEdition.ToLower())
    # Niveau 2
    New-Level "le nombre de commandes de type Cmdlet" (Get-Command -CommandType Cmdlet | Measure-Object).Count
    # Niveau 3
    New-Level "le nombre de DLL Windows dont le nom commence par 'K'" (Get-ChildItem C:\Windows\System32\k*.dll).Count
    # Niveau 4
    New-Level "le numero de serie du Bios sans espace (ComputerInfo)" (Get-CimInstance -ClassName Win32_BIOS).SerialNumber.Replace(' ','')
    # Niveau 5
    New-Level "le 'MachineID' dans la cle de registre 'HKLM:\SOFTWARE\Microsoft\SQMClient'" (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\SQMClient").MachineID
    # Niveau 6
    New-Level "l'identifiant universel unique (UUID) du systeme Windows" (Get-CimInstance Win32_ComputerSystemProduct).UUID
    # Niveau 7
    New-Level "l'identifiant de securite (SID) de l'utilisateur PowerQuest$Script:level" (Get-LocalUser "PowerQuest$Script:level").SID.Value
    # Niveau 8
    $alea = Get-Random -Maximum 1000
    New-Item "C:\Users\PowerQuest$Script:level\Documents\$alea" -Force
    New-Level "le nom de la cmdlet equivalente a 'mount' + le nom du fichier dans Documents" ((Get-Alias mount).Definition + (Get-ChildItem).Name)
    # Niveau 9
    New-Level "l'Adresse Mac de l'adaptateur '$(Get-NetAdapter).Name'" (Get-NetAdapter).MacAddress
    # Niveau 10
    New-Level "l'Adresse IPv4 de l'adaptateur '$(Get-NetAdapter).Name'" (Get-NetAdapter | Get-NetIPAddress).IPv4Address
    # Niveau 11
    For($i=1;$i -lt (Get-Random -Maximum 1000);$i++) {
        $item = New-Item "C:\Users\PowerQuest$Script:level\Documents\A ranger\$(Get-Random -Maximum 1000)$i" -ItemType ('File','Directory' | Get-Random) -Force
    }
    New-Level "le nombre de fichiers dans les Documents 'A ranger'" (Get-ChildItem "C:\Users\PowerQuest$Script:level\Documents\A ranger" -File).Count
    # Niveau 12
    New-Level "le nombre de capacites Windows non presentes sur le systeme en ligne" (Get-WindowsCapability -Online | Where-Object State -eq NotPresent).Count
    # Niveau 13
    For($i=1;$i -lt (Get-Random -Maximum 1000);$i++) {
        (New-Item "C:\Users\PowerQuest$Script:level\Documents\Confidentiels\$(Get-Random -Maximum 1000)$i" -ItemType ('File','Directory' | Get-Random) -Force).Attributes = 'Hidden'
    }
    New-Level "le nombre de dossiers caches dans les Documents 'Confidentiels'" (Get-ChildItem "C:\Users\PowerQuest$Script:level\Documents\Confidentiels" -Directory -Hidden).Count
    # Niveau 14
    $alea = Get-Random -Maximum 1000
    (New-Item "C:\Users\PowerQuest$Script:level\Documents\Coffre Fort" -Value $alea -Force).Attributes = 'Hidden'
    New-Level "la valeur de NPARA_PASSWORD a la ligne 846 du script systeme 'winrm.vbs' + le code secret du document cache" ((Get-Content C:\windows\system32\winrm.vbs)[846].Split('"')[1] + $alea)
    # Niveau 15
    New-Level "le nombre de services en cours d'execution et en type de demarrage manuel" (Get-Service | Where-Object StartType -eq Manual | Where-Object Status -eq Running).Count
    # Niveau 16
    New-Level "le nombre de services qui dependent directement du service 'Remote Procedure Call'" (Get-Service RPCSS -DependentServices).Count
    # Niveau 17
    New-Level "le nombre de proprietes de l'objet 'Process'" (Get-Process | Get-Member -MemberType Properties).Count
    # Niveau 18
    $fourniture = 'stylo','crayon','gomme','bloc-notes','agrafeuse','trombones','ciseaux','regle','calculatrice' | Get-Random
    New-Item "C:\Users\PowerQuest$Script:level\Desktop\$fourniture" -Force
    New-Level "la fourniture sur le bureau + le nombre de variables d'environnement du système" ($fourniture + (Get-ChildItem Env:).Count)
    # Niveau 19
    (New-Item "C:\Users\PowerQuest$Script:level\Documents\Confidentiels\PassPhrase" -Value "éclair âpre sur l'île ô combien unique des îlots émerveillés" -Force).Attributes = 'Hidden'
    New-Level "la phrase secrete dans les Documents 'Confidentiels', toute en MAJUSCULES et sans espace" (Get-Content "C:\Users\PowerQuest$Script:level\Documents\Confidentiels\PassPhrase").toUpper().Replace(' ','')
}
function Initialize-Game {
    $Script:level=0
    Remove-Item C:\Users\PowerQuest* -Recurse -Force -Confirm:$false
    Get-LocalUser PowerQuest* | Remove-LocalUser -ErrorAction SilentlyContinue
    Remove-Item C:\Users\Malus -Force
    Disable-PasswordComplexity
    (New-Item C:\Users\Malus -Force).Attributes = 'Hidden'
    New-Item C:\Users\PowerQuest0\Documents -ItemType Directory -Force
    Build-Levels
}
Export-ModuleMember -Function Initialize-Game,Get-Solution,Get-Instruction