この記事について
TryHackMeの「Windows PowerShell」というルームで学んだ内容を、Task単位でまとめたノートです。Cyber Security 101の「Command Line」モジュールの2番目のルームで、前段の「Windows Command Line」に続いて、より強力なシェルであるPowerShellの基本を学びます。cmdletの命名規則から、ファイル操作、パイプによるフィルタリング、システム・ネットワーク情報の取得、そしてリモート実行(Invoke-Command)まで一通り扱う内容でした。
課題の設問や答え、フラグはここには含めていません。あくまで各Taskで学んだコマンドの使い方や考え方を、自分の理解として整理したものです。
Task 1: 導入
このルームは「Command Line」モジュールの2番目のルームで、前作にあたる「Windows Command Line」の知識を土台にしています。前提知識として「Windows and AD Fundamentals」モジュールの内容も挙げられていました。
PowerShellは、歴史的に見るとWindows向けの2番目のコマンドラインツールです。この位置づけを意識しておくと、この先何度も出てくる「従来のCommand Promptとの比較」がすんなり頭に入ってきました。
学んだこと
新しいツールを学ぶときは、いきなり単体で理解しようとするより、「何の代わりにできたのか」「前のツールの何が不便だったのか」という文脈を先に押さえておくと飲み込みが早いと感じました。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| PowerShell | Microsoft製のコマンドラインシェル兼スクリプト言語 |
| Command Prompt(cmd.exe) | PowerShellより先に作られたWindowsの伝統的なコマンドラインツール |
| Command Lineモジュール | Windows Command Line → Windows PowerShell → Linux Command Lineと続く学習モジュール |
Task 2: PowerShellとは何か
このTaskの一番のポイントは、PowerShellが「テキストではなくオブジェクトをやり取りする」設計になっているという点でした。
従来のコマンドライン(cmd.exeなど)は、コマンドの実行結果がただの文字列として返ってきます。次のコマンドでその結果を使いたければ、自分で文字列を切り貼りしたりパース(parsing、解析)したりする必要があります。一方PowerShellでは、cmdlet(コマンドレット、PowerShell用のコマンドの呼び方)を実行すると、プロパティ(properties、特性)とメソッド(methods、動作)を持った「オブジェクト」がそのまま返ってきます。次のコマンドに渡すときも、欲しいプロパティを名前で指定するだけで済みます。
開発の背景も興味深く、MicrosoftのエンジニアであるJeffrey Snover氏が、「WindowsはAPIで構造化データを扱うのに対し、Unixはすべてをテキストとして扱う」という違いに着目し、オブジェクト指向のアプローチと.NET frameworkを組み合わせて2006年にリリースしたのがPowerShellだそうです。2016年にはオープンソース・クロスプラットフォーム版のPowerShell Coreも登場し、Windows専用ツールという枠を超えています。
学んだこと
「オブジェクトでやり取りする」という一文だけだとピンと来ませんでしたが、「次のコマンドに渡すときにテキスト加工が要らない」という具体的なメリットに置き換えると、この先のTaskで出てくるパイプ処理のありがたみが最初から見えてきました。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| object-oriented | オブジェクト指向。データとメソッドをひとまとめにした「オブジェクト」を扱う考え方 |
| cmdlet | PowerShell用のコマンド単位。「動詞-名詞」の形式で命名される |
| .NET framework | PowerShellの土台になっているMicrosoftのソフトウェア開発基盤 |
| PowerShell Core | 2016年公開のオープンソース・クロスプラットフォーム版PowerShell |
Task 3: PowerShellの基本
まずラボ環境への接続作業から始まります。AttackBox(演習用のブラウザ上マシン)から、RemminaというクライアントソフトでSSH(Secure Shell、暗号化された通信でリモート操作するプロトコル)接続し、ターゲットのWindows VMに入ります。今回はCommand Promptからしかアクセスできない設定だったので、powershellと打ってPowerShellを起動する流れでした。
このTaskの本題は、cmdletの命名規則です。PowerShellのcmdletは必ず**Verb-Noun(動詞-名詞)**の形をしていて、例えばGet-Contentなら「Get(取得する)」+「Content(中身)」で「ファイルの中身を取得する」という意味になります。この規則のおかげで、初めて見るcmdletでも大体何をするものか予想がつきます。
調べ方の基本セットとして、次の3つを覚えました。
-
Get-Command: 今使えるコマンド一覧を表示する -
Get-Help: コマンドの使い方を教えてくれる(-examplesオプションで具体例も見られる) -
Get-Alias: エイリアス(cmdletの短縮名・別名)の一覧を表示する
エイリアスについては、実際に自分で触っているうちに命名の傾向に気づきました。Get-Contentがgc、Get-Memberがgm、New-Itemがniというように、多くのエイリアスは動詞の頭文字+名詞の頭文字で作られています。ただし全部がこの規則というわけではなく、Get-ChildItemはgcがGet-Contentに取られているためgci(childのcとitemのiを両方使う)になっていたり、ls・cat・cd(Unix由来)やdir・copy・del(cmd.exe由来)のような、他のシェルからの移行者向けの互換エイリアスも別枠で用意されていたりします。目的の違う2系統のエイリアスが混在している、という整理をすると納得できました。
また、コマンドの検索パターンには*(アスタリスク)を使ったワイルドカード(wildcard、任意の文字列に一致する記号)が使え、クォート("や')なしでそのまま指定できることも学びました。
学んだこと
エイリアス1つとっても、「短くするための工夫」と「他OS/他シェルからの移行者への配慮」という2つの異なる設計意図が混ざっていると知り、単なる暗記対象ではなく「なぜこの名前なのか」を考えると覚えやすくなると感じました。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| Verb-Noun | cmdletの命名規則。「動詞-名詞」の形(例: Get-Content) |
| alias | cmdletの短縮名・別名。gc(Get-Content)のような頭文字型と、ls(Get-ChildItem)のような他シェル互換型がある |
wildcard(*) |
任意の文字列に一致させるための記号 |
| Find-Module / Install-Module | オンラインリポジトリからモジュール(cmdletの集まり)を検索・インストールするcmdlet |
Task 4: ファイルシステムの操作
このTaskは、ファイル・フォルダ操作系cmdletのオンパレードでした。ポイントは、Command Promptの対応コマンドと1対1で紐づけながら覚えられることです。
| Command Prompt(従来) | PowerShell | やること |
|---|---|---|
| dir | Get-ChildItem | 一覧表示 |
| cd | Set-Location | 移動 |
| md(フォルダ)/なし(ファイル) | New-Item | 新規作成 |
| rmdir / del | Remove-Item | 削除 |
| copy | Copy-Item | コピー |
| move | Move-Item | 移動 |
| type | Get-Content | 中身の表示 |
表からもわかる通り、Command Promptではフォルダ用・ファイル用でコマンドが分かれていた操作(作成・削除)が、PowerShellではNew-Item・Remove-Itemのように1つのcmdletにまとまっています。これはTask 2で出てきた「オブジェクト指向」の考え方が活きている部分で、PowerShellにとってはファイルもフォルダも同じ「Item」というオブジェクトとして扱われているからです。
学んだこと
新しいコマンド体系を覚えるとき、「前のツールでは何個のコマンドに分かれていたか」を比較すると、統合された設計の意図がよくわかりました。ファイルとフォルダを区別せず「Item」として扱う発想は、この先PowerShellの他の場面でも繰り返し出てきそうです。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| Get-ChildItem | 指定した場所のファイル・ディレクトリを一覧表示するcmdlet(dir/lsに相当) |
| Set-Location | カレントディレクトリを変更するcmdlet(cdに相当) |
| New-Item / Remove-Item | ファイルやディレクトリを作成・削除するcmdlet |
| Item | PowerShellでファイルとフォルダを区別せず扱う共通の概念 |
Task 5: パイプ・フィルタリング・ソート
このTaskは、パイプ(|)を使ったデータの絞り込み・並び替えがテーマでした。パイプは「あるコマンドの出力を、そのまま次のコマンドの入力として渡す」仕組みで、コマンドA | コマンドBと書くと「Aの結果をBに渡す」という意味になります。
Task 2の「オブジェクトでやり取りする」という特徴が、ここで実際に活きてきます。Get-ChildItem | Sort-Object Lengthと書けば「ファイル一覧を取得して(オブジェクトのまま)、Lengthというプロパティで並び替える」ことができます。テキストでのやり取りなら、サイズの数字部分を自分で抜き出して比較するコードを書かないといけないところを、PowerShellではプロパティ名を指定するだけで済みます。
登場する主なcmdletは3つです。
-
Where-Object: 条件に合うものだけ残す(絞り込み)。Get-ChildItem | Where-Object -Property Extension -eq .txtのように、比較演算子と組み合わせて使う -
Select-Object: 表示するプロパティや件数を絞る -
Select-String: ファイルの中身をテキスト検索する(Unix系のgrepやCommand Promptのfindstrに相当)。正規表現(regex)にも対応
比較演算子は他の言語(Bash、Pythonなど)とも共通する考え方で、-eq(equal、等しい)・-ne(not equal、等しくない)・-gt(greater than、より大きい)・-ge(greater than or equal、以上)・-lt(less than、より小さい)・-le(less than or equal、以下)の6つを押さえておけば大抵のフィルタリングに対応できます。
学んだこと
Where-Object(絞り込み)とSelect-Object(表示項目の選択)は名前が似ていて最初混同しそうになりましたが、「どの行を残すか」と「どの列を見せるか」という役割の違いで整理すると迷わなくなりました。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
piping(pipe, |) |
あるコマンドの出力を次のコマンドの入力として渡す技法 |
| Where-Object | 条件に基づいてオブジェクトを絞り込むcmdlet |
| Select-Object | 特定のプロパティを選択したり、件数を制限したりするcmdlet |
| comparison operator | 比較演算子。-eq, -ne, -gt, -ge, -lt, -le など |
Task 6: システム・ネットワーク情報の取得
システム管理者向けの、静的な情報を取得するcmdlet群を学ぶTaskでした。
-
Get-ComputerInfo: OS・ハードウェア・BIOSなど、システム構成全体のスナップショットを1コマンドで取得できる。従来のsysteminfoより詳細 -
Get-LocalUser: ローカルユーザーアカウントの一覧を、ユーザー名・有効状態(enabled)・説明(description)付きで表示する -
Get-NetIPConfiguration/Get-NetIPAddress: ネットワークインターフェースやIPアドレスの構成情報を取得する。従来のipconfigに相当
後半は、この3つのcmdletを組み合わせて実際にラボ環境を調査する実践パートでした。Get-LocalUserでユーザー一覧を眺めていると、見慣れたシステムアカウントに混じって毛色の違うアカウントが見つかり、そのホームフォルダをGet-ChildItemとGet-Contentでたどっていく、という一連の流れを自分の手で組み立てる課題でした。具体的な調査結果や見つけたものはここには書きませんが、「一覧を取得する→怪しいものを見つける→掘り下げる」という調査の型そのものが、実務のインシデント対応にも通じる考え方だと感じました。
学んだこと
このTaskで初めて「複数のcmdletを自分で組み合わせて目的の情報にたどり着く」という課題が出てきました。個々のコマンドを覚えることと、それらを繋げて調査の筋道を立てることは別のスキルなのだと実感しました。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| Get-ComputerInfo | OS・ハードウェア・BIOSなど包括的なシステム情報を取得するcmdlet |
| Get-LocalUser | ローカルユーザーアカウントの一覧を表示するcmdlet |
| Get-NetIPConfiguration / Get-NetIPAddress | ネットワーク設定・IPアドレスの詳細を表示するcmdlet |
| description(プロパティ) | Get-LocalUserの出力に含まれる、アカウントの説明文 |
Task 7: リアルタイムのシステム分析
Task 6が「静的な設定」を見る内容だったのに対し、このTaskは「動的な、今この瞬間の状態」を見るcmdletがテーマでした。
-
Get-Process: 今動いているプロセスの一覧(タスクマネージャーの「プロセス」タブに相当) -
Get-Service: Windowsサービス(バックグラウンドで動く常駐プログラム)の状態一覧。不正なサービスが仕込まれていないか調べるのにも使われる -
Get-NetTCPConnection: 今どんなTCP通信が行われているかを一覧表示する。攻撃者と通信しているマルウェアの発見(インシデント対応)にも使われる -
Get-FileHash: ファイルのハッシュ値(データから生成される固定長の値)を計算する。ファイルが改ざんされていないかの検証に使う
Get-NetTCPConnectionについては、単に接続一覧を見るだけでなく、「どのプロセス(プログラム)がその接続を開いているか」まで一緒に取得できます。プロセスID(PID)を手がかりにGet-Processと組み合わせれば、「知らない外部アドレスと通信しているプロセスがいないか」を突き止める、という実務的な調査の流れが体験できました。
ADS(Alternate Data Streams、代替データストリーム)という概念も改めて登場しました。NTFS(Windowsの標準ファイルシステム)が持つ機能で、1つのファイルに目に見えない追加のデータストリームを付加できる仕組みです。ADSに書き込んだデータは通常の一覧表示やファイルサイズには現れないため、マルウェアがデータを隠す・データを持ち出す手口として悪用されることがある、というセキュリティ上の意味合いも含めて復習になりました。
学んだこと
「一覧を取得する」cmdletの中には、単なる状態表示以上に、調査の手がかりになるプロパティ(所有プロセスの情報など)がさりげなく含まれていると知り、出力をただ眺めるだけでなく「他に何と組み合わせられそうか」を考える視点が持てるようになった気がします。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| Get-Process / Get-Service | 実行中のプロセス・サービスの状態一覧を表示するcmdlet |
| Get-NetTCPConnection | 現在のTCP接続と、それを所有するプロセスの情報を表示するcmdlet |
| Get-FileHash | ファイルのハッシュ値を計算し、改ざんの有無を検証するcmdlet |
| ADS(Alternate Data Streams) | NTFSの機能で、ファイルに隠しデータストリームを付加できる仕組み |
Task 8: スクリプティングとリモート実行
前半はスクリプティング(scripting)、つまり複数のコマンドをテキストファイルにまとめて自動実行する考え方の紹介でした。面白かったのは、同じPowerShellスクリプティングという技術が、ブルーチーム(blue team、防御側、ログ分析やマルウェア調査の自動化)にもレッドチーム(red team、攻撃側、偵察やリモートコマンド実行の自動化)にも使われる、と説明されていた点です。攻めにも守りにも使える技術、というのがサイバーセキュリティらしい構図だと思いました。
後半はInvoke-Commandについて。これは「別のマシン(リモート)でコマンドを実行する」ためのcmdletで、-FilePathで用意済みのスクリプトを走らせる方法と、-ScriptBlock { ... }でその場のコマンドをそのまま実行する方法の2通りが紹介されていました。
このcmdlet、実は-ComputerName(接続先)を指定しなければローカル(自分自身のマシン)で実行されるだけなので、最初は「リモート実行のはずなのに接続先を指定してないのはなぜ?」と混乱しました。調べていくと、リモートで実行するには接続先の指定に加えて、相手側でPSRemoting(PowerShellのリモート操作機能)やWinRM(Windows Remote Management)が有効になっている必要があり、さらに正しい認証情報も要る、ということがわかりました。
ここで気になったのが、「その認証情報自体が盗まれていたら意味がないのでは」という点です。実際、正規の管理者アカウントの認証情報を奪った攻撃者が、すでに侵害した内部端末を踏み台にして他のマシンへInvoke-Commandを実行していく手口は、ラテラルムーブメント(lateral movement、侵入後に攻撃範囲を横に広げていくフェーズ)として実際のインシデントでもよく見られるものだそうです。「誰が実行したか」というログだけでは正規の操作と見分けがつかないため、防御側は「いつもと違う動き」を検知する振る舞い検知(EDRやSIEMによるアノマリー検知)や、管理者権限を階層ごとに分離するTiered Administration、社内ネットワークだからといって無条件に信頼しないゼロトラスト(Zero Trust)といった、複数の対策を重ねる考え方(defense in depth、多層防御)で臨む必要がある、という話に発展しました。1つのコマンドの裏に、これだけの攻撃・防御の設計思想が絡んでいるのは、学んでいて素直に面白いと感じた部分です。
学んだこと
「便利な機能ほど、悪用されたときの影響範囲も大きい」というのは頭では分かっていたつもりでしたが、Invoke-Commandを通して「では悪用されたときにどう検知するか」まで自分で考えてみると、単一の対策では守り切れないという多層防御の必要性が具体的に腑に落ちました。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| Invoke-Command | リモートシステム上でコマンドやスクリプトを実行するcmdlet |
| PSRemoting / WinRM | PowerShellのリモート操作を可能にする仕組み |
| lateral movement(ラテラルムーブメント) | 侵入後、他のマシンへ攻撃範囲を広げていく攻撃フェーズ |
| defense in depth(多層防御) | 単一の対策に頼らず、複数の防御層を重ねる考え方 |
| Zero Trust(ゼロトラスト) | ネットワークの内外を問わず、都度アクセスを検証する考え方 |
Task 9: まとめ
最後は締めくくりのTaskで、設問も「準備ができたらチェックを押すだけ」の内容でした。このルームの次は、モジュール内の3番目のルーム「Linux Command Line」に進む流れになっています。Windows Command Line → Windows PowerShell → Linux Command Lineという構成で、コマンドラインの基礎を一通り学べるようになっているようです。
学んだこと
このルームを通して、単発のコマンドを覚えること以上に、「調べる→組み合わせる→怪しいものを見つける」という調査の型と、「便利な機能には裏返しのリスクもある」という視点の両方が身についたように思います。次のLinux Command Lineルームでは、今回学んだWindows側の知識とどう対応づけられるかを意識しながら進めていきたいです。
関連キーワード
| キーワード(英語) | 説明 |
|---|---|
| Linux Command Line | Command Lineモジュールの次のルーム。Linux版のコマンドラインを学ぶ |