Skip to content
Please update to the latest release 0.77.3 to address Multiple CVEs.
Windows.System.Powershell.PSReadline

Windows.System.Powershell.PSReadline

Extracts PowerShell command history from PSReadline ConsoleHost_history.txt files.

PowerShell is commonly used by attackers across all stages of the attack lifecycle. The PSReadline module is responsible for command history and from PowerShell 5 on Windows 10, the default configuration saves a copy of the console history to disk.

There are several parameters available for search leveraging regex:

  • SearchStrings enables regex search over a PSReadline line.
  • StringWhiteList enables a regex whitelist for results.
  • UserRegex enables a regex search on Username
  • UploadFiles enables upload ConsoleHost_history.txt in scope

name: Windows.System.Powershell.PSReadline
description: |
  Extracts PowerShell command history from PSReadline
  `ConsoleHost_history.txt` files.

  PowerShell is commonly used by attackers across all stages of the
  attack lifecycle. The PSReadline module is responsible for command
  history and from PowerShell 5 on Windows 10, the default
  configuration saves a copy of the console history to disk.

  There are several parameters available for search leveraging regex:
  - SearchStrings enables regex search over a PSReadline line.
  - StringWhiteList enables a regex whitelist for results.
  - UserRegex enables a regex search on Username
  - UploadFiles enables upload ConsoleHost_history.txt in scope

author: Matt Green - @mgreen27

reference:
  - https://attack.mitre.org/techniques/T1059/001/
  - https://0xdf.gitlab.io/2018/11/08/powershell-history-file.html

type: CLIENT

parameters:
  - name: ConsoleHostHistory
    default: \AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
  - name: SearchStrings
    default: .
    type: regex
  - name: StringWhiteList
    default:
    type: regex
  - name: UserRegex
    default: .
    type: regex
  - name: UploadFiles
    description: "Upload ConsoleHost_history.txt files in scope"
    type: bool

precondition:
  SELECT OS From info() where OS = 'windows'

sources:
  - query: |
        -- First extract target ConsoleHost_history path for each user
        LET targets = SELECT Name as Username,
           { SELECT Mtime, Atime, Ctime, Btime, Size, OSPath
             FROM stat(filename=expand(path=Directory) + ConsoleHostHistory)
           } AS Stat
        FROM Artifact.Windows.Sys.Users()
        WHERE Directory and Username =~ UserRegex AND Stat.OSPath

        -- Extract targets PSReadline entries
        SELECT * FROM foreach(
        row=targets,
        query={
            SELECT Stat, count() AS LineNum,
                   Line,
                   Username,
                   Stat.OSPath AS OSPath
            FROM parse_lines(filename=Stat.OSPath)
            WHERE LineNum
             AND Line =~ SearchStrings
             AND NOT if(condition=StringWhiteList,
                        then=Line =~ StringWhiteList,
                        else=FALSE)
        })

  - name: Upload
    query: |
        -- if configured upload ConsoleHost_history.txt in results
        SELECT * FROM if(condition=UploadFiles,
            then={
                SELECT
                    Username,
                    upload(file=Stat.OSPath) as ConsoleHost_history
                FROM targets
            })