Windowsサービスの概要
Windowsシステムはバックグラウンドで様々なプログラムが動いています。例えばセキュリティソフトやバックアップツール、Microsoftのユーザーエクスペリエンス向上プログラムなどが挙げられますね。
サービスは、Windowsシステム上で常駐して(設定次第では要求時などに)実行されるプログラムを指し、ユーザーのログイン状態に関わらず動きます。
よって、特段UIなどを介したユーザーとの対話を必要とせずに常時動き続けるソフトウェアは多く、サービス化されています。
概念的にはUNIX系統におけるデーモンと似ていますが、一般的な常駐アプリやスタートアップとは上記のような点で明確に挙動が異なります。また、通常のWindowsアプリケーションをサービス化して運用することも可能です。
Visual StudioにはWindowsサービスアプリケーションのプロジェクトテンプレートがあるため、簡単なものであればMicrosoftのリファレンスに沿ってすぐに作成することができます。
サーバー管理はもちろん、単純処理の効率化を図るためにサービスを自作してみるのも面白いと思います。
例えば、バックアップやメール転送ツールは定期的な処理が必要です。このような処理を常駐アプリで行うのは少し憚られます。通知がうるさかったり、ポップアップウィンドウが出現して都度クリック操作を求められたり、タスクバーが混雑したりするのは個人的に好みではありません。
この観点でいえばWindows起動時や終了時、あるいはファイルの状況を逐次的に判断してOneDriveへアクセスする(1)サービスは確かに有用だと言えますね。
認証の制御、データの整合性を保つ、複数デバイス間でのファイルの同期、フォルダの監視などといったシステムの構築はサーバー管理に求められる技術かと思いますが、サービスを利用することでこれらの処理を自動的に実行できます。
このような、定期的な処理の自動化、簡単化はサービスの運用利点の一つです。
サービスの確認方法は PowerShell やコントロールパネル、コンピュータの管理画面など様々ですが、コマンドプロンプトにて sc コマンドを使用するのが手軽かと思います。
sc 単体ではヘルプが表示されます。引数にqueryを付与してサービスの詳細を表示します。
sc query
全て取得する場合はstate=allを付与してください。
sc query state=all | findstr /B SERVICE_NAME
サービスを安易に削除してしまうとシステムに致命的な損害が発生する恐れがあるので気軽には言えませんが、明らかに不要そうなものがあった場合は停止したいかもしれません···そんなときは下記を入力してください。
sc stop
なお、start, stop には net コマンドも利用可能です。こちらはサービス側の処理を待ってからコマンド制御へ戻る同期型の挙動となっていますので必要に応じて使い分けてください。
*全てのサービスのパス一覧を出力する*場合は PowerShell で以下を試してみてください。
cmd /c "sc query state=all | findstr SERVICE_NAME" | % { cmd /c "sc qc " $_.split(" ")[1] } | findstr PATH
Windowsサービスを利用した管理者権限の奪取
突然物騒ですがサービスはその仕様上、悪意を持って利用されるケースもあります。攻撃対象のWindowsに侵入した攻撃者が、任意のコマンドを実行するためにサービスを利用する例について見ていきます。
まず、サービス起動時の挙動を追っていきましょう。
サービスが以下のようなパスに存在した時、Service1を起動してみます。
C:\service\vulnerable path\Service1.exe
この場合サービスのパスはスペースを含み、かつ” “で囲われていません。
Windowsは上記のスペース時点、すなわち C:\service\vulnerable まででパスが終了しているか、スペースを含むパスであるのかを判断しかねます。
そこでWindowsはスペースでパスが終了すると一旦解釈し、C:\service\vulnerableを探索します。該当サービスが無ければ C:\service\vulnerable path\Service1.exe をパスと解釈して再度探索します。
では、危険なプログラムが C:\service フォルダ内に配置され、さらに vulnerable.exe という名前に書き換わっていた場合はどうなるでしょう。
- C:\service\vulnerable が探索される
- vulnerable.exeが発見、実行される
という手順を踏むことで、例えばvulnerable.exeとしてリバースシェルを配置すれば、システム権限のシェルが獲得できます。
*実際にサービスのパスを見てみる*と C:\Program Files\* など、スペースを含むパスの場合には全体が” “で囲われていることが分かると思います。
Windowsサービスというシステム自体に危険があるわけではありませんが、前述の通りユーザーのサインイン状態に関わらない、かつバックグラウンドで実行されるため、一度不正なサービスを実行されると検知もしづらく厄介です。
実際、ユーザーエクスペリエンス向上のためにキーロガーが動いていたりすることは往々にしてありますが、それらが不正に注入されたそれと正確な判定基準で区別されているかと詰問されると非常に苦しいのではないでしょうか。ペネトレーションテストの際はこういったシステムの裏側で動くプログラムが何をしているのかまでを調査する必要があることが分かるかと思います。サーバーなどを管理する際は特に気をつけたいですね。
後書鬼鮫
まともなタイトルが思いつかなくて···というよりいざサービスを作ってみると特に記事として書きたいことが見当たらずタイトルは迷走し、OGPのことを考慮すると冒頭にそれらしき画像を用意した方が良いと考えましたがそもそもサービスにまつわるイメージが某某某ー某・某ー某某(2)のサービスマンとエ某ゲリヲンの次回予告くらいしか浮かばなかったので迷走したタイトルに寄せてしまいました。
クリスマスツリーの電飾に因んだモンスターの調整を置いておきます。
?:実数値(努力値) 調整意図
- H:189(244) 10n-1
- A:84(0)
- B:94(20) DL調整
- C:242(212) 11n
- D:95(28) DL調整
- S:104(4) 端数
@命の珠 電磁砲 10万ボルト エナジーボール マジカルシャイン 8世代環境でのトリル運用を想定しているためトリルディアルガからの繰り出しから全抜きを狙うのが主な運用であり、ダメ計は基本的にザシアン、カイオーガを基準にしている。 さもなくば耐久を落として S:114(84) 60振りスイクン抜き にするとギャラのケアも多少できるため、単体運用でも安定する。 11nアンチの皆さんも(私も多少その気があるが)この記事の公開予定日が12/11であるとなればきっと納得いただけるだろう。
今のところ9世代環境はすごく面白いですね。サンタさんも未来ではS136ですしね。
でも人にサザンドラの耐久調整の話すると嫌われますから、こういう話を嬉々としてするのは普段は必要以上に控えているつもりです。これは本当の話で、中学生くらいになると皆分かっている雰囲気を出し始めますから、何も私がでしゃばらなくても良いのです。
全くの怪文書失礼しました。ヘルクレスオキシデンタリスでした。
注釈
1.C#でOneDriveへの定期的なアクセスを行う一例です···が自信はありません。
using System;
using System.IO;
using System.ServiceProcess;
using Microsoft.OneDrive.Sdk;
namespace BackupService
{
public partial class BackupService : ServiceBase
{
private Timer timer;
private IOneDriveClient oneDriveClient;
private string backupPath;
private string backupFolder;
public BackupService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// Initialize OneDrive client
oneDriveClient = OneDriveClientExtensions.GetClientUsingWebAuthenticationBroker();
// Set the backup path and folder
backupPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Backup");
backupFolder = "MyBackupFolder";
// Create the backup folder on OneDrive if it doesn't exist
var item = oneDriveClient.Drive.Root.ItemWithPath(backupFolder).Request().GetAsync().Result;
if (item == null)
{
oneDriveClient.Drive.Root.Children.Request().AddAsync(new Item
{
Name = backupFolder,
Folder = new Folder()
}).Wait();
}
// Set the timer to run the backup every day
timer = new Timer();
timer.Interval = 24 * 60 * 60 * 1000; // 24 hours
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// Check if the backup folder exists on the local machine
if (!Directory.Exists(backupPath))
{
return;
}
// Create a list of files in the backup folder
var files = Directory.GetFiles(backupPath);
// Upload each file to the backup folder on OneDrive
foreach (var file in files)
{
using (var stream = File.OpenRead(file))
{
var fileName = Path.GetFileName(file);
oneDriveClient.Drive.Root.ItemWithPath(backupFolder + "/" + fileName).Content.Request().PutAsync<Item>(stream).Wait();
}
}
}
protected override void OnStop()
{
// Stop the timer
timer.Stop();
timer.Dispose();
}
}
}
2.正式な漢字表記は母母母ー母・母ー母母ですが中国語表記だと波波波ー波・波ー波波だったりします。