1

I'm trying to get a session cookie using PowerShell and InternetExplorer.Application but nothing seems to work.

There is no $ie.Document.cookie variable. The session cookie is not available to JavaScript(because it is http-only)

# Create an ie com object
$ie = New-Object -ComObject "InternetExplorer.Application" 
$ie.visible = $true; 
$ie.navigate2("https://www.example.com/login");
# Wait for the page to load 
while ($ie.Busy -eq $true) { Start-Sleep -Milliseconds 1000; }
#Add login details 
$ie.Document.getElementById("username").value = "user"; 
$ie.Document.getElementById("password").value = "1234";
$ie.Document.getElementsByName("login_button")[0].Click();
while($ie.Busy -eq $true) { Start-Sleep -Milliseconds 1000; }
$div = $ie.Document.getElementsByTagName('div')[0];
$ie.navigate("javascript: window.location=document.cookie.match(new RegExp('(^| )csrf_token=([^;]+)'))[2]");
while($ie.Busy -eq $true) { Start-Sleep -Milliseconds 1000; }
$csrf = $ie.LocationUrl.Substring(32);
echo $csrf;
#Stop-Process -Name iexplore
$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

$cookie = New-Object System.Net.Cookie     
$cookie.Name = "user_name"
$cookie.Value = "user"
$cookie.Domain = "www.example.com"
$session.Cookies.Add($cookie);

$cookie = New-Object System.Net.Cookie     
$cookie.Name = "user_session_id"
$cookie.Value = "What I need"
$cookie.Domain = "www.example.com"
$session.Cookies.Add($cookie);

Invoke-WebRequest -URI "https://www.example.com/demo/my_file&csrf_token=$csrf" -WebSession $session -OutFile 'finally.zip';
echo 'Done!';

Note that the only way I found to get the csrf is to use javascript to get the value to the url, but I can't do it with the user_session_id because it is marked as http_only.

ShadowBeast
  • 135
  • 1
  • 2
  • 6

2 Answers2

7

Take a look at these options to incorporate into what you already have.

First, get the cookies

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession

Get-Content .\cookie.txt | 
foreach {
$line = $_ -split '/' | select -First 1

$tokens=$line.Split("`t").TrimEnd()

    $c = @{
        name=$tokens[0]
        value=$tokens[1]
        domain=$tokens[2]
    }

    $cookie = New-Object System.Net.Cookie
    $cookie.Name=$c.name
    $cookie.Value=$c.Value
    $cookie.Domain=$c.domain

    $session.Cookies.Add($cookie)
}

Getting Cookies using PowerShell

Here are two straightforward ways to get website cookies within PowerShell.

$url = "https://www.linkedin.com" 
$webrequest = Invoke-WebRequest -Uri $url -SessionVariable websession 
$cookies = $websession.Cookies.GetCookies($url) 


# Here, you can output all of $cookies, or you can go through them one by one. 

foreach ($cookie in $cookies) { 
     # You can get cookie specifics, or just use $cookie 
     # This gets each cookie's name and value 
     Write-Host "$($cookie.name) = $($cookie.value)" 
}
postanote
  • 15,138
  • 2
  • 14
  • 25
  • Is the reverse possible? I would like to store values from `Get-ComputerInfo` in a cookie or a [localstorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) or [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) on a client using powershell. An internal website should be able to read this information in. – surfmuggle Jun 10 '22 at 17:26
  • I've personally not had a need to do the reverse, so, that would require some research. – postanote Jun 10 '22 at 19:19
0

Credits To : hochwald.net

Found the following Function ( just copy and paste it ) that worked like charm :

Usage Example :

Invoke-WebRequest -UseBasicParsing -Uri "https://web.mywebsite.com/UserSecurity" -WebSession $session


$cookies = Get-AllCookiesFromWebRequestSession $session


foreach ($cookie in $cookies) 
{ 
    Write-Host "$($cookie.name) = $($cookie.value)"
}


Function :

function Get-AllCookiesFromWebRequestSession
{
   <#
         .SYNOPSIS
         Get all cookies stored in the WebRequestSession variable from any Invoke-RestMethod and/or Invoke-WebRequest request

         .DESCRIPTION
         Get all cookies stored in the WebRequestSession variable from any Invoke-RestMethod and/or Invoke-WebRequest request
         The WebRequestSession stores useful info and it has something that some my know as CookieJar or http.cookiejar.

         .PARAMETER WebRequestSession
         Specifies a variable where Invoke-RestMethod and/or Invoke-WebRequest saves values.
         Must be a valid [Microsoft.PowerShell.Commands.WebRequestSession] object!

         .EXAMPLE
         PS C:\> $null = Invoke-WebRequest -UseBasicParsing -Uri 'http://jhochwald.com' -Method Get -SessionVariable WebSession -ErrorAction SilentlyContinue
         PS C:\> $WebSession | Get-AllCookiesFromWebRequestSession

         Get all cookies stored in the $WebSession variable from the request above.
         This page doesn't use or set any cookies, but the (awesome) CloudFlare service does.

           .EXAMPLE
         $null = Invoke-RestMethod -UseBasicParsing -Uri 'https://jsonplaceholder.typicode.com/todos/1' -Method Get -SessionVariable RestSession -ErrorAction SilentlyContinue
         $RestSession | Get-AllCookiesFromWebRequestSession

         Get all cookies stored in the $RestSession variable from the request above.
         Please do not abuse the free API service above!

         .NOTES
         I used something I had stolen from Chrissy LeMaire's TechNet Gallery entry a (very) long time ago.
         But I needed something more generic, independent from the URL! This can become handy, to find any cookie from a 3rd party site or another host.

         .LINK
         https://docs.python.org/3/library/http.cookiejar.html

         .LINK
         https://en.wikipedia.org/wiki/HTTP_cookie

         .LINK
         https://gallery.technet.microsoft.com/scriptcenter/Getting-Cookies-using-3c373c7e

         .LINK
         Invoke-RestMethod

         .LINK
         Invoke-WebRequest
   #>

   [CmdletBinding(ConfirmImpact = 'None')]
   param
   (
      [Parameter(Mandatory,
         ValueFromPipeline,
         ValueFromPipelineByPropertyName,
         Position = 0,
         HelpMessage = 'Specifies a variable where Invoke-RestMethod and/or Invoke-WebRequest saves values.')]
      [ValidateNotNull()]
      [Alias('Session', 'InputObject')]
      [Microsoft.PowerShell.Commands.WebRequestSession]
      $WebRequestSession
   )

   begin
   {
      # Do the housekeeping
      $CookieInfoObject = $null
   }

   process
   {
      try
      {
         # I know, this look very crappy, but it just work fine!
         [pscustomobject]$CookieInfoObject = ((($WebRequestSession).Cookies).GetType().InvokeMember('m_domainTable', [Reflection.BindingFlags]::NonPublic -bor [Reflection.BindingFlags]::GetField -bor [Reflection.BindingFlags]::Instance, $null, (($WebRequestSession).Cookies), @()))
      }
      catch
      {
         #region ErrorHandler
         # get error record
         [Management.Automation.ErrorRecord]$e = $_

         # retrieve information about runtime error
         $info = [PSCustomObject]@{
            Exception = $e.Exception.Message
            Reason    = $e.CategoryInfo.Reason
            Target    = $e.CategoryInfo.TargetName
            Script    = $e.InvocationInfo.ScriptName
            Line      = $e.InvocationInfo.ScriptLineNumber
            Column    = $e.InvocationInfo.OffsetInLine
         }

         # output information. Post-process collected info, and log info (optional)
         $info | Out-String | Write-Verbose

         $paramWriteError = @{
            Message      = $e.Exception.Message
            ErrorAction  = 'Stop'
            Exception    = $e.Exception
            TargetObject = $e.CategoryInfo.TargetName
         }
         Write-Error @paramWriteError

         # Only here to catch a global ErrorAction overwrite
         exit 1
         #endregion ErrorHandler
      }
   }

   end
   {
      # Dump the Cookies to the Console
      ((($CookieInfoObject).Values).Values)
   }
}